Intent.ACTION_GET_CONTENT是否需要READ_EXTERNAL_STORAGE权限才能读取Uri?

11
我想知道,如果我启动以下Intent.ACTION_GET_CONTENT
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("application/zip");
startActivityForResult(intent, RequestCode.REQUEST_CHOOSE_BACKUP_FILE);

尝试以以下方式从意图中读取返回的Uri。

Uri uri = data.getData();

// Figure out extension
ContentResolver contentResolver = getContext().getContentResolver();
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
final String extension = mimeTypeMap.getExtensionFromMimeType(contentResolver.getType(uri));

File temp = null;
try {
    temp = File.createTempFile(Utils.getJStockUUID(), "." + extension);
} catch (IOException e) {
    e.printStackTrace();
}

// Delete temp file when program exits.
temp.deleteOnExit();

InputStream inputStream = null;
OutputStream outputStream = null;

try {
    inputStream = getContext().getContentResolver().openInputStream(uri);
    outputStream = new FileOutputStream(temp);

    byte[] buffer = new byte[8 * 1024];
    int bytesRead;
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        outputStream.write(buffer, 0, bytesRead);
    }
} catch (IOException e) {
    Log.e(TAG, "", e);
} finally {
    close(outputStream);
    close(inputStream);
}

READ_EXTERNAL_STORAGE 权限是否必要?

我进行了一些测试,令我惊讶的是,我可以在不请求 READ_EXTERNAL_STORAGE 的情况下成功读取。

我只是想确认,在所有类型的情况下,从 Intent.ACTION_GET_CONTENT 读取 Uri 确实不需要 READ_EXTERNAL_STORAGE 权限。


理论上来说不应该需要。但实际上,ACTION_GET_CONTENT 实现中的 bug 可能会迫使你保持该权限。 - CommonsWare
需要权限的 Uri 看起来像 /storage/emulated/0/Download/jstock_backup_12-jun-2018.zip。不需要权限的 Uri 看起来像 /document/acc=1;doc=3566/document/454 - Cheok Yan Cheng
@CommonsWare 谢谢。为了提供更好的用户体验,我们计划仅在 Uri 需要权限时请求权限。您知道任何好的方法来执行此类检查,以确定 Uri 是否需要权限吗? - Cheok Yan Cheng
你知道任何好的方法来执行这样的检查,以确定Uri是否需要权限吗?-- 如果它具有file方案,则可能需要该权限。 - CommonsWare
1
Android 5和Android 6模拟器的默认画廊应用程序提供的URI仍需要权限。 - fluidsonic
显示剩余6条评论
1个回答

5

我曾经遇到过用户安装了第三方文件管理器(File Manager+)的情况,如果在使用ACTION_GET_CONTENT获取Uri时没有先授予READ_EXTERNAL_STORAGE权限,那么从Uri中读取内容会失败并显示权限错误(只有在用户选择文件时使用了第三方应用程序时才会出现该问题,如果使用Google Drive或正常系统选择,则无需权限即可正常工作)。

我通过在带有Play Store的模拟器上安装File Manager+并尝试使用它来复制此行为。


感谢您提供一些边缘案例。我刚刚在Android 8上使用文件管理器+进行了测试。是的,为了正确读取所选文件,需要权限。 - Cheok Yan Cheng
2
对我来说,即使没有读取权限,一切都可以正常工作,甚至使用了提到的文件管理器+应用程序,但是一些用户报告了SecurityException崩溃,所以我会尝试这个解决方案。不过这确实很奇怪。 - Miloš Černilovský
@MilošČernilovský 对我来说,即使使用文件管理器+也可以正常工作,你是否检查了你的Crashlytics是否与此有关的崩溃,或者这只发生在以前的版本中? - Aman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接