我正试图为我的小企业(只有3人)创建一个应用程序,允许用户(我)选择一个csv文件,让它转换数据,并将其保存为新的csv。我能够成功地从我直接带入android studio的文件中读取和操作数据,我有一个工作文件选择器,可以访问最近的文档。但是,我无法选择文档或下载文件夹中的任何文件。如能提供帮助将不胜感激。
编辑:添加了额外的代码,并澄清了我有问题的部分。
下面是我的文件选择器的代码。我会完全诚实地说,我在网上找到了大部分代码,并不完全确切地说它是如何工作的,因为大多数Android文档和示例都显示了弃用的版本
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
}
下面是我如何调用read(在别处完成的实际计算和操作)
fun readCSV(path:String): BufferedReader {
val inputStream: InputStream? = contentResolver.openInputStream(Uri.parse(path))
//return BufferedReader(InputStreamReader(assets.open("Test.csv")))
return BufferedReader(InputStreamReader(inputStream))
}
下面是android清单中的权限部分。我实际上并不需要访问相机,但是请求权限对话框甚至没有显示存储权限,所以我正在检查是否有不同的权限。是的
<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()
}
Image of non selectable file that I want selectable
Image of only selectable location I can find (can't save files here)
1条答案
按热度按时间k4emjkb11#
在
ContentResolver
上调用openInputStream()
,以获取Uri
标识的内容上的InputStream
。理想情况下,您应该将
Uri
交给一个视图模型或其他可以在后台线程上执行内容I/O的东西。