安卓Kotlin 使用ContentResolver 调用系统文件管理器 读取/写入文件

读取文件(N以上无需存储权限)

  • 为兼容Android N以下设备,需要检查存储权限
  1. AndroidManifest.xml中添加如下声明(位于application标签之外)
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  1. 编写检查函数
private fun checkReadPermission(): Boolean {
    
    
	return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    
    
		ActivityCompat.requestPermissions(this,arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),1)	//requestCode = 1
		false
	} else true
}
  1. 编写选择文件函数
private fun pickFile() {
    
    
	val i = Intent(Intent.ACTION_GET_CONTENT)
	i.type = "*/*"
	startActivityForResult(i, 1)
}
  1. onRequestPermissionsResult中处理requestCode
override fun onRequestPermissionsResult(requestCode: Int,permissions: Array<String?>,grantResults: IntArray) {
    
    
	when (requestCode) {
    
    
    	1 -> {
    
    
        	if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) pickFile()
            else Toast.makeText(this, R.string.permissionDenied, Toast.LENGTH_SHORT).show()
        }
    }
}
  1. 因为pickFile函数的startActivityForResult调用了其它应用,所以需要设置onActivityResult
private fun generateCacheFile(name: String) = File(cacheDir, name)

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    
    
	super.onActivityResult(requestCode, resultCode, data)
    if (resultCode == RESULT_OK) when (requestCode) {
    
    
    	1 -> data?.data?.let {
    
     saveFile(generateCacheFile("input"), it) }
    }
}
  1. 编写获取uri后打开FileInputStream读取文件进行保存的函数,这里将其存储在了cache目录下的input文件
private fun saveFile(f: File?, uri: Uri) {
    
    
	val fd = contentResolver.openFileDescriptor(uri, "r")
    fd?.fileDescriptor?.let {
    
    
    	val fi = FileInputStream(it)
        f?.outputStream()?.let {
    
    
        	fi.copyTo(it)
            it.close()
        }
        fi.close()
    }
    fd?.close()
}

保存文件

  1. 编写自定义保存文件名函数
private fun createFile(fileName: String, type: String = "*/*"){
    
    
	val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
    intent.addCategory(Intent.CATEGORY_OPENABLE)
    intent.type = type
    intent.putExtra(Intent.EXTRA_TITLE, fileName)
    startActivityForResult(intent, 2)	//requestCode = 2
}
  1. 因为createFile函数的startActivityForResult调用了其它应用,所以需要设置onActivityResult
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    
    
	super.onActivityResult(requestCode, resultCode, data)
    if (resultCode == RESULT_OK) when (requestCode) {
    
    
    	//1 -> data?.data?.let { saveFile(generateCacheFile("input"), it) }
    	2 -> data?.data?.let {
    
     save2Uri(it) }
    }
}
  1. 编写保存文件函数
private fun generateCacheFile(name: String) = File(cacheDir, name)

private fun save2Uri(uri: Uri){
    
    
	val outputFile = generateCacheFile("output")
    contentResolver.openOutputStream(uri)?.let {
    
    
    	val fi = outputFile.inputStream()
        fi.copyTo(it)
        fi.close()
        it.close()
    }
}

猜你喜欢

转载自blog.csdn.net/u011570312/article/details/111357739
今日推荐