【问题标题】:_data column not available at FileProvider uri_data 列在 FileProvider uri 中不可用
【发布时间】:2018-09-12 02:54:24
【问题描述】:

我正在使用 FileProvider 模式为文件创建 content:// uri,使用

FileProvider.getUriForFile(this, "com.myapp.provider", file) 

功能。我有清单、provider_paths 和一切都设置了标准方式,它创建了一个类似 content://com.myapp.provider/external_files/music/mysong.mp3 的 uri。

我的问题是,如果我尝试在另一个应用程序中获取真实文件路径,它不起作用,因为 _data 列不存在(具体来说,日志中的错误是 E/CursorWindow: Failed to read row 0, column -1 from a CursorWindow which has 1 rows, 0 columns.)。为了获取真实路径,我使用了非常标准的函数

final String column = MediaStore.Files.FileColumns.DATA;
final String[] projection = { column  };
try {
    cursor = context.getContentResolver().query(uri, projection, null, null, null);
    if (cursor != null && cursor.moveToFirst()) {
        final int column_index = cursor.getColumnIndexOrThrow(column);
        return cursor.getString(column_index);
    }
} finally {
    if (cursor != null)
        cursor.close();
}

如果我使用不同的应用程序来共享同一个文件,它会生成一个类似content://com.otherapp.provider/external_files/music/mysong.mp3 的 uri,我已经可以从中检索到真实的文件路径。任何想法我必须做些什么来确保我的应用程序正确地将给定的 uri 插入到 ContentResolver?不允许使用手动contentResolver.insert(...) 函数。我尝试了不同版本的 provider_paths.xml 并授予给定 uri 所有可能的读/写权限,但我永远无法检索到真实路径。

我生成的 uri 本身工作正常,因为我可以读取文件或播放歌曲,我的问题是我无法检索我需要的真实文件路径。

谢谢

【问题讨论】:

  • 又一个...没有正确的方法来获取“真实文件路径”,故事结束。你也不需要它。

标签: android file path uri android-contentresolver


【解决方案1】:

我的问题是,如果我尝试在另一个应用程序中获取真实文件路径

其他应用不应尝试这样做。

为了获取真实路径,我使用的也是非常标准的函数

这适用于极少数Uri 值。

如果我使用不同的应用程序来共享同一个文件,它会生成一个类似于 content://com.otherapp.provider/external_files/music/mysong.mp3 的 uri,我已经可以从中检索到真实的文件路径。

不能保证。

有什么想法可以确保我的应用正确地将给定的 uri 插入 ContentResolver?

你没有。您修复了客户端应用程序,它不应该尝试从 Uri 获取“真实文件路径”。

我的问题是我无法检索我需要的真实文件路径。

相反,对于带有content 方案的Uri

第 1 步:通过在某些 Context 上调用 getContentResolver()(例如,活动)来获取 ContentResolver

第 2 步:在 ContentResolver 上调用 openInputStream(),传入您的 Uri,以获取该内容的 InputStream

第 3 步:通过 InputStream 消费内容

如果您正在使用一些只能处理文件的第三方库,请将数据从该InputStream 复制到某个FileOutputStream,然后将生成的文件与该库一起使用。

这样,无论内容来自何处(您可以访问的文件、您无法访问的文件、数据库中的 BLOB 列等),您都将拥有可以工作的代码。

另见:

【讨论】:

  • 我使用第三方图像处理库,该库仅适用于文件路径,并且严重依赖文件扩展名来帮助它解码所述文件。我可以按照您的建议从流中创建一个新文件,但我需要原始文件的文件扩展名或完整文件名和扩展名,无论如何这可以通过 URI 传递吗?
  • @Asiimwe:不。Uri 不需要指向任何可能曾经是任何地方的文件的任何内容。您可以获得 MIME 类型,并且可以尝试使用 MimeTypeMap 派生文件扩展名,但不能保证为 Uri 报告的 MIME 类型对于 MimeTypeMap 是已知的。您可以获得“显示名称”,但不要求它是文件名。如果您绝对需要一个文件,use a file-picker library 仅适用于文件系统,而不是 ACTION_GET_CONTENTACTION_OPEN_DOCUMENT 等。
猜你喜欢
  • 2016-04-08
  • 2013-09-22
  • 2017-07-19
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2020-08-31
  • 2017-07-04
相关资源
最近更新 更多