我正在使用文件选择器让用户选择数据输入文件(.txt)。经过一番研究,我终于找到了一个解决方案,可以使用 ActivityResultLauncher 避免任何已弃用的方法:
使用以下方式声明 filePicker:
private var filePicker: ActivityResultLauncher<String>? = null
在我的片段的 onAttach 方法中注册文件选择器,调用:
private fun registerFilePicker() {
filePicker = registerForActivityResult<String, Uri>(
ActivityResultContracts.GetContent()
) { uri: Uri? -> onPickFile(uri) }
}
打开文件选择器:
private fun openFilePicker() {
val mimeType = "*/*"
filePicker!!.launch(mimeType)
}
对用户选择的文件触发操作:
private fun onPickFile(uri: Uri?) {
try {
requireActivity().contentResolver.openInputStream(uri!!).use { inputStream ->
inputStream?.let {
it.reader().useLines { lines ->
lines.forEach {
val mot = it.substringBefore(',')
if (!(mot in Mots))
importListLine.add(Import(mot, it.substringAfter(','), true ))
}
adapter?.setImportList(importListLine)
adapter?.notifyDataSetChanged()
binding.btnSave.isVisible = true
binding.btnCancel.isVisible = true
}
}
}
} catch (exception: IOException) {
}
}
到目前为止效果还不错。但我现在想要的是在我自己的目录 uri 中打开文件选择器,这应该可以通过以下方式实现:
putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri)
有人可以告诉这个应该添加到哪里吗?
看来要自定义意图(例如,为选择器定义初始 uri),最好是重写 createIntent 方法。我尝试过,但没有完全正常运行(我的初始 uri 被忽略)。
同时,我在medium.com上找到了Abdul Hamid(感谢他)的以下解决方案,该解决方案既紧凑又非常适合我:
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.DocumentsContract
import android.provider.OpenableColumns
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
class YourActivity : AppCompatActivity() {
private val requestFileLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
result.data?.data?.let { uri ->
handleSelectedFile(uri)
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Replace "your_folder_name" with the actual folder name you want to open
// as example: "Downloads", "Documents"
openSpecificFolder("your_folder_name")
}
private fun openSpecificFolder(folderName: String) {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "*/*" // Set the MIME type to filter files
val uri = Uri.parse("content://com.android.externalstorage.documents/document/primary:$folderName")
putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri)
}
requestFileLauncher.launch(intent)
}
private fun handleSelectedFile(uri: android.net.Uri) {
val cursor = contentResolver.query(uri, null, null, null, null)
cursor?.use {
if (it.moveToFirst()) {
val displayName = it.getString(it.getColumnIndex(OpenableColumns.DISPLAY_NAME))
// Do something with the file name
}
}
}
}
如果您在片段而不是主活动中工作,只需声明并初始化 contentResolver,如下所示:
val contentResolver = getActivity().getContentResolver()