【问题标题】:Get filenames for results returned from ActivityResultContracts.OpenMultipleDocuments() contract获取从 ActivityResultContracts.OpenMultipleDocuments() 合约返回的结果的文件名
【发布时间】:2020-08-23 06:22:32
【问题描述】:

在我的 Android 应用中,我启动了一个文档选择器,以便用户可以将一些文档导入我的应用:

this.intentlauncherchoosedoc = this.registerForActivityResult(
    new ActivityResultContracts.OpenMultipleDocuments(), 
    new ActivityResultCallback<List<Uri>>() {
        @Override
        public void onActivityResult(List<Uri> urilist) {
            for (Uri uri : urilist) {
                String filename = uri.getLastPathSegment();
                createdoc(uri, filename);
            }
        }
    }   
);

不幸的是,当用户选择一个文档时,返回的 uri 是这样的:

content://com.google.android.apps.docs.storage/document/acc=1;doc=encoded=mgMyynWh7Lrq1qW1dradGc60EJWehheCQiS5mYY7a8CF80Ouzro=

有什么方法可以获取所选文档的原始文件名,以便我可以保存该文件名并将其列出给我的用户,当他们查看他们导入的文档时?

【问题讨论】:

  • 您可以尝试DocumentFile.fromSingleUri().getName() 尝试获取文档的“显示名称”。这可能是也可能不是文件名,因为用户选择的内容可能是也可能不是文件。
  • @CommonsWare 我阅读了您在关闭此问题时提供的链接答案,虽然我知道它不能保证文件名存在,但关于如何获取文件名和我想到了。我想将其发布为我自己问题的答案,但这太快了。通过内容解析器查询元数据让我可以访问文件名,如果有的话,这是一个合理的答案......但它不包含在您的链接答案中。
  • 通读文档后,我了解了如何通过查询与 uri 关联的元数据来访问文件名:Cursor cursor = getContentResolver().query(incominguri, null, null, null, null); String filename = null; if (cursor != null) { int nameindex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); cursor.moveToFirst(); filename = cursor.getString(nameindex); cursor.close(); }
  • 请注意,这不一定是文件名,您需要防范未能实现OpenableColumns支持的数据源。

标签: android android-activity android-fileprovider


【解决方案1】:

为了方便其他人搜索,这里是示例 Kotlin 代码,用于打开 单个 文件并检索其名称和内容。 GetContent() 的使用保证DISPLAY_NAME 列将包含在返回的元数据中。

    private val getFile = registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
        requireActivity().contentResolver.apply { 
            query(uri, null, null, null, null)?.use { cursor ->
                val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
                cursor.moveToFirst()
                cursor.getString(nameIndex)
            }?.let { fileName ->
                openInputStream(uri)?.use { stream ->
                    presenter.addFile(fileName, stream)
                }
            }
        }
    }

并将其链接到按钮:

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        view.findViewById<Button>(R.id.chooseFile).setOnClickListener {
            getFile.launch("*/*")
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 2011-04-22
    • 2021-04-26
    • 1970-01-01
    • 2019-05-10
    相关资源
    最近更新 更多