使用上下文提供者的数据或请求 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 变得无效
我也有同样的问题,
然后你尝试以下变通方法:
Android 5.1.1 lollipop return null file path if image chosen from gallery
您可以在使用 "Google Photo" 应用程序时重现此 SecurityException 日志。
此问题的主要原因是 "Google Photo" 与 "content://com.google.android.apps.photos.contentprovider/1/1" 等固定字符串共享 ContentUri 并将其与静态临时值连接。 "Google Photo"在实际Activity或接收Intent.ACTION_SEND的Context时不提供文件路径。可能是"Google Photo"的政策,不把私有图片文件暴露给其他app。
例如,您在 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);
}
我的应用程序允许用户从其他应用程序导入他们的照片和视频。现在 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 变得无效
我也有同样的问题, 然后你尝试以下变通方法:
Android 5.1.1 lollipop return null file path if image chosen from gallery
您可以在使用 "Google Photo" 应用程序时重现此 SecurityException 日志。
此问题的主要原因是 "Google Photo" 与 "content://com.google.android.apps.photos.contentprovider/1/1" 等固定字符串共享 ContentUri 并将其与静态临时值连接。 "Google Photo"在实际Activity或接收Intent.ACTION_SEND的Context时不提供文件路径。可能是"Google Photo"的政策,不把私有图片文件暴露给其他app。
例如,您在 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);
}