【问题标题】:Using data from context providers or requesting Google Photos read permission?使用来自上下文提供者的数据或请求 Google 相册读取权限?
【发布时间】:2015-06-01 11:24:13
【问题描述】:

我的应用允许用户从其他应用导入他们的照片和视频。现在谷歌用谷歌照片取代了谷歌+照片,我遇到了一些事情。其中之一是在应用重新启动后重新使用导入的文件。我有一种感觉,当 Google 照片返回带有图像 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提供的文件时也遇到了同样的问题

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

【问题讨论】:

    标签: android android-contentprovider google-photos


    【解决方案1】:

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

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

    【讨论】:

    • 这也是我的结论,所以我会选择你的答案作为答案。谢谢
    • 它看起来像反模式。在主线程中复制文件?
    • @tse 只要您的意图所针对的活动没有停止,您就可以从任何线程访问
    • 我遇到了类似的问题,我可以通过使用 ACTION_OPEN_DOCUMENT 而不是 ACTION_PICK 来解决它。我相信 ACTION_OPEN_DOCUMENT 授予持久权限并且不像 ACTION_PICK 那样严格。当我使用 ACTION_PICK 时,当我在一个活动中获取 URI 并转到另一个活动来显示图像时,我失去了权限,正如开发人员文档所说。
    • @onusopus 谢谢,你的答案应该是公认的答案。
    【解决方案2】:
    1. 您可以在使用“Google 照片”应用时重现此 SecurityException Log。

    2. 此问题的主要原因是“Google 照片”与“content://com.google.android.apps.photos.contentprovider/1/1”等固定字符串共享 ContentUri,并将其与静态临时连接价值观。 “Google Photo”在接收到 Intent.ACTION_SEND 的实际 Activity 或 Context 时不提供文件路径。也许,这是“Google Photo”的政策,不将私人图像文件暴露给其他应用程序。

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

    所以,我建议你在Activity A上临时保存文件,在Activity B上使用临时文件路径

    【讨论】:

    • 谢谢!我认为你的回答对我的问题是正确的。
    • 我也有同样的问题,谷歌照片会导致很多问题:-/
    【解决方案3】:

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

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

    【讨论】:

    • 您可以使用输入流访问文件吗?像“context.getContentResolver().openInputStream(uri);” ?
    • 这正是我在获得权限错误时正在做的事情
    【解决方案4】:

    看起来this 问题很相似

    我认为当活动(而不是片段)死亡时 - 它检索到的所有 URI 都将失效

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

    【讨论】:

    • 是的,它看起来确实很相似,但我认为新照片应用内容提供商的权限发生了变化,因为我感觉我之前尝试过该权限但没有运气。我最终将文件复制到我的领土并在我的内容提供商中注册以保留访问权限。如果您找到更好的解决方案,请告诉我!
    【解决方案5】:

    您需要为所有符合您意图的软件包明确设置权限。 它通常发生在 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);
            }
    

    【讨论】:

      【解决方案6】:

      【讨论】:

      • 我的问题不是最初的 get 调用 - 这是权限保留。获得文件访问权限后,如果应用暂停或用户离开应用,则访问权限被撤销
      • 请在此处包含答案,而不仅仅是链接。见meta.stackexchange.com/questions/8231/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-14
      • 2023-03-19
      • 1970-01-01
      相关资源
      最近更新 更多