我正在尝试使用 Intent.ACTION_GET_CONTENT
打开文件。
根据文件浏览器打开的 Android 版本/设备品牌,我得到以下结果:
从 Downloads
中选择一个文件:
content://com.android.providers.downloads.documents/document/446
从 Fotos
选择文件:
content://media/external/images/media/309
从 FileCommander
选择文件:
file:///storage/emulated/0/DCIM/Camera/20141027_132114.jpg
我可以打开所有这些文件,除非我尝试从 Downloads,
, Audio
, Afbeeldingen
打开文件(图片)
我可能无法处理这种 Uri: content://com.android.providers.downloads.documents/document/446
我尝试了以下内容:
- 尝试通过 new File(uri.getPath()) 打开文件。 File.exists() 返回 false。
- 尝试通过 getContext().getContentResolver().openInputStream(uri) 打开/访问文件。结果变成 FileNotFoundException
- 尝试使用以下代码打开文件:
public static String getRealPathFromURI_API19(Context context, Uri uri) {
Log.i("uri", uri.getPath());
String filePath = "";
if (uri.getScheme().equals("file")) {
return uri.getPath();
} else if (DocumentsContract.isDocumentUri(context, uri)) {
String wholeID = DocumentsContract.getDocumentId(uri);
Log.i("wholeID", wholeID);
// Split at colon, use second item in the array
String[] splits = wholeID.split(":");
if (splits.length == 2) {
String id = splits[1];
String[] column = {MediaStore.Images.Media.DATA};
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{id}, null);
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
}
} else {
filePath = AttachmentUtils.getPath(context, uri);
}
return filePath;
}
我究竟做错了什么?
更新:我注意到屏幕截图中列出的文件实际上并不存在于存储中。我使用的设备是该公司的平板电脑,其中包含垃圾数据。我的同事告诉我,这个设备曾经与另一个谷歌账户相关联。这些文件可能是以前帐户中不再存在/无法访问的文件。
我自己的结论是我在 Android 中遇到了一些错误。我的 错误报告
2017 年 2 月 6 日更新:
Android 禁止 file://
URI。请考虑考虑。
禁止文件:Uri 方案 到目前为止,Android 7.0 最大的兼容性问题是文件:Uri 值的方案实际上被禁止了。如果您尝试传递一个文件:Intent 中的 Uri,该 Intent 将传递给另一个应用程序——无论是通过额外的还是作为 Intent 的“数据”方面——您将因 FileUriExposedException 异常而崩溃。将 file: Uri 值放在剪贴板上的 ClipData 中时,您将面临类似的问题。这来自 StrictMode 的更新版本。 StrictMode.VmPolicy.Builder 有一个 penaltyDeathOnFileUriExposure() 方法触发检测文件:Uri 值和由此产生的 FileUriExposedException 异常。而且,这似乎是预先配置的,就像预先配置 StrictMode 以应用 penaltyDeathOnNetwork() 的方式一样(您的 NetworkOnMainThreadException 崩溃的来源)。
原文由 com2ghz 发布,翻译遵循 CC BY-SA 4.0 许可协议
使用下面的代码。这肯定会起作用。
使用以下代码浏览任何格式的文件。
然后在 onActivityResult 中获取该文件路径,如下所示。
在此之后,您可以通过适当的操作从保存文件的应用程序外部存储中打开此文件。