Android _数据列在FileProvider uri处不可用

Android _数据列在FileProvider uri处不可用,android,file,path,uri,android-contentresolver,Android,File,Path,Uri,Android Contentresolver,我使用FileProvider模式来创建文件的content://uri,其中 FileProvider.getUriForFile(this, "com.myapp.provider", file) 功能。我将清单、提供者路径和所有内容设置为标准方式,它会创建一个uri,如content://com.myapp.provider/external_files/music/mysong.mp3 我的问题是,如果我尝试在另一个应用程序中获取真实的文件路径,它将无法工作,因为\u data列不存

我使用FileProvider模式来创建文件的content://uri,其中

FileProvider.getUriForFile(this, "com.myapp.provider", file) 
功能。我将清单、提供者路径和所有内容设置为标准方式,它会创建一个uri,如
content://com.myapp.provider/external_files/music/mysong.mp3

我的问题是,如果我尝试在另一个应用程序中获取真实的文件路径,它将无法工作,因为
\u data
列不存在(具体来说,日志中的错误是
E/CursorWindow:无法从一个有1行0列的CursorWindow中读取第0行,第1列。
)。对于获取真实路径,我使用的也是非常标准的函数

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();
}
如果我使用不同的应用程序共享同一个文件,它会生成一个uri,如
content://com.otherapp.provider/external_files/music/mysong.mp3
,我已经可以从中检索到真实的文件路径。我该怎么做才能确保我的应用程序正确地将给定的uri插入ContentResolver?不允许使用手动
contentResolver.insert(…)
函数。我尝试了不同版本的provider_paths.xml,并将所有可能的读/写权限授予给定的uri,但我永远无法检索到真正的路径

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

谢谢

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

其他应用程序不应尝试执行此操作

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

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();
}
这对很少的
Uri
值有效

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

这不是保证

我该怎么做才能确保我的应用程序正确地将给定的uri插入ContentResolver

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

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

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

步骤1:通过在某些
上下文(例如活动)上调用
getContentResolver()
,获取
ContentResolver

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

第三步:通过
InputStream

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

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

另见:


又一个。。。并没有合适的方法来获取“真正的文件路径”,故事的结尾。我使用的是第三方图像处理库,它只处理文件的路径,并且严重依赖文件扩展名来帮助它解码所述文件。我可以按照您的建议,从流中创建一个新文件,但我需要文件扩展名,或者原始文件的完整文件名和扩展名,这是否可以通过URI传递?@Asimwe:不。不要求
URI
指向任何可能曾经是文件的地方。您可以获得MIME类型,并且可以尝试使用
MimeTypeMap
来派生文件扩展名,但是不能保证
MimeTypeMap
知道为该
Uri
报告的MIME类型。您可以获得“显示名称”,但不要求它是文件名。如果您确实需要一个文件,它只适用于文件系统,而不是
ACTION\u GET\u CONTENT
ACTION\u OPEN\u DOCUMENT
等。