Android(Kotlin) API33+文件选择器无法访问文档/下载文件夹求助
问题:无法选择文档/下载文件夹中的CSV文件
我正在为小型企业(仅3人使用)开发一款APP,支持选择CSV文件、转换数据并保存为新CSV文件。目前可成功读取并处理直接导入Android Studio的文件,且已实现可访问最近文档的文件选择器,但无法选择文档或下载文件夹中的文件。现附上相关代码及截图,恳请帮助解决问题。
编辑补充:新增代码并明确问题点。
文件选择器代码
private var uriToFile:String = "Path" private var fileImportCompletionHandler: (Uri.()->Unit)? = null private val fileImportIntentLauncher = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result: ActivityResult -> if (result.resultCode == Activity.RESULT_OK) { val intent = result.data intent?.data?.let { uri -> Log.i("MYTAG","uri at first check is $uri") fileImportCompletionHandler?.invoke(uri) ?: run { // TODO() warn } fileImportCompletionHandler = null val p = uri.path Log.i("MYTAG","p is $p") } ?: run { // TODO() warn } } else { // TODO() warn } } private val importIntent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) type = "text/csv" } fun showActionOpenDocument(completion: Uri.()->Unit) { fileImportCompletionHandler = completion fileImportIntentLauncher.launch(importIntent) }
调用代码
binding.btnImport.setOnClickListener { //requestPermission() showActionOpenDocument { uriToFile = this.toString() binding.tvPath.text = uriToFile }
读取逻辑代码
fun readCSV(path:String): BufferedReader { val inputStream: InputStream? = contentResolver.openInputStream(Uri.parse(path)) //return BufferedReader(InputStreamReader(assets.open("Test.csv"))) return BufferedReader(InputStreamReader(inputStream)) }
AndroidManifest权限配置
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA" />
权限请求代码
private val requestPermissionLauncher = registerForActivityResult( ActivityResultContracts.RequestPermission() ) { isGranted: Boolean -> if (isGranted) { // Permission is granted. Continue the action or workflow in your // app. Log.i("MYTAG", "isGranted = true") } else { // Explain to the user that the feature is unavailable because the // feature requires a permission that the user has denied. At the // same time, respect the user's decision. Don't link to system // settings in an effort to convince the user to change their } } fun requestPermission(){ when{ ContextCompat.checkSelfPermission( vContext, Manifest.permission.READ_EXTERNAL_STORAGE ) == PackageManager.PERMISSION_GRANTED -> { //Permission is Granted Log.i("MYTAG","Permission Granted") } ActivityCompat.shouldShowRequestPermissionRationale( vActivity, Manifest.permission.READ_EXTERNAL_STORAGE ) -> { //Permission denied : Additional Rational should be displayed Log.i("MYTAG","Permission Denied") showRationaleDialog("TCG Inventory Converter", "TCG Inventory Converter needs access to your External Storage"+ "\n"+"\n"+"REASON: Required to import and export CSV Files ") } else -> { // Permission has not been asked yet Log.i("MYTAG","Permission Requested") requestPermissionLauncher.launch( Manifest.permission.READ_EXTERNAL_STORAGE ) } } } private fun showRationaleDialog(title:String, message:String){ val builder: AlertDialog.Builder = AlertDialog.Builder(vContext) builder.setTitle(title) .setMessage(message) .setPositiveButton("Cancel"){ dialog, _-> dialog.dismiss() } .setNegativeButton("Open Permissions"){ dialog, _ -> dialog.run { val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) val uri = Uri.fromParts("package","com.example.filereadtest",null) intent.data =uri startActivity(intent) } } builder.create().show() }
截图说明
- 想要选择的不可选文件:文档/下载文件夹中的CSV文件无法选中
- 唯一可选位置:仅能访问最近文档,该路径无法保存文件
内容的提问来源于stack exchange,提问作者LetsGoRidePandas
相关产品推荐
相关产品推荐

