使用上下文提供者的数据或请求 Google 照片读取权限?

Using data from context providers or requesting Google Photos read permission?

我的应用程序允许用户从其他应用程序导入他们的照片和视频。现在 Google 将 Google+ Photos 替换为 Google Photos,我遇到了一些问题。其中之一是在应用重启后重新使用导入的文件。我有一种感觉,当 Google Photos returns 图像 URI 的意图时,他们已经收紧了给出的权限,所以在我的应用程序被杀死后,它不再具有访问上传文件的权限。我得到了安全预期:

java.lang.SecurityException: Permission Denial: opening provider com.google.android.apps.photos.contentprovider.MediaContentProvider from ProcessRecord{2c17ab9e 2124:com.myapp.myapp/u0a436} (pid=2124, uid=10436) that is not exported from uid 10427

编辑:

我在重复使用 com.google.android.apps.docs.sync.filemanager.FileProvider

提供的文件时也遇到了同样的问题

有suggestions/workaround吗?我知道我可以在失去权限之前阅读该文件,所以理论上我可以复制它,但我不能说我非常喜欢这个..

或许您可以尝试将此用户权限添加到您的清单文件中。

<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />

看起来this问题很相似

我认为当 activity(不是片段)消亡时 - 它检索到的所有 URI 都会失效

我也遇到了同样的问题 - 试图在后台上传图片。但是 UI 线程中的用户可能会更改 activity 并且 URI 变得无效

我也有同样的问题, 然后你尝试以下变通方法:

  1. Android 5.1.1 lollipop return null file path if image chosen from gallery

  2. https://gist.github.com/alexzaitsev/75c9b36dfcffd545c676

  1. 您可以在使用 "Google Photo" 应用程序时重现此 SecurityException 日志。

  2. 此问题的主要原因是 "Google Photo" 与 "content://com.google.android.apps.photos.contentprovider/1/1" 等固定字符串共享 ContentUri 并将其与静态临时值连接。 "Google Photo"在实际Activity或接收Intent.ACTION_SEND的Context时不提供文件路径。可能是"Google Photo"的政策,不把私有图片文件暴露给其他app。

  3. 例如,您在 Manifest 文件中定义了 2 Activity,Actvity A 和 Activity B。Activity A 用于接收 Intent.ACTION_SEND。 Activity B 用于处理图像文件。 Activity A 将意图转发给 Activity B。然后 Activity B 不是正确的 Activity 到 "Google Photo",您遇到了 SecurityException。

所以,我建议你把文件暂时保存在ActivityA,使用临时文件路径在ActivityB

是的,这是设计使然,如 Android Developer site 所述。

出于安全原因,权限是临时的,因此一旦客户端应用程序的任务堆栈完成,就无法再访问该文件。您必须在 onActivityResult 方法中收到意向答案时获取文件数据。存储文件数据的副本,因为当 onActivityResult returns.

时文件将不再可用

您需要为符合您意图的所有包明确设置权限。 它通常发生在 Android 4.4 中。

您可以使用此实用程序来执行此操作:

List<ResolveInfo> resInfoList = getContext().getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        for (ResolveInfo resolveInfo : resInfoList) {
            String packageName = resolveInfo.activityInfo.packageName;
            getContext().grantUriPermission(packageName, imageFileUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }