如何使用ActivityResultLauncher设置文件选择器的原始uri

问题描述 投票:0回答:1

我正在使用文件选择器让用户选择数据输入文件(.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)

有人可以告诉这个应该添加到哪里吗?

kotlin directory filepicker
1个回答
0
投票

看来要自定义意图(例如,为选择器定义初始 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()
© www.soinside.com 2019 - 2024. All rights reserved.