java.lang.SecurityException: 权限拒绝:打开提供程序com.google.android.apps.photos.content.GooglePhotosImageProvider

20

突然间,我开始在运行Android 4.3及以上版本的设备上收到以下异常

java.lang.SecurityException: Permission Denial: opening provider com.google.android.apps.photos.content.GooglePhotosImageProvider from ProcessRecord{454ca9d0 5914:com.propertymanager/u0a10231} (pid=5914, uid=10231) requires com.google.android.apps.photos.permission.GOOGLE_PHOTOS or com.google.android.apps.photos.permission.GOOGLE_PHOTOS
        at android.os.Parcel.readException(Parcel.java:1431)
        at android.os.Parcel.readException(Parcel.java:1385)
        at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2896)
        at android.app.ActivityThread.acquireProvider(ActivityThread.java:4755)
        at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2480)
        at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1152)
        at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:759)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:665)
        at android.content.ContentResolver.openInputStream(ContentResolver.java:500)
        at com.myapp.xxxx.determineCorrectScale(SourceFile:148)

导致这个问题的代码是

    public static int determineCorrectScale(Context con, Uri imagUri) {
        int scale = 1;
        InputStream imageStream = null;

                imageStream = con.getContentResolver().openInputStream(imagUri);
.
.
.
    }

需要帮忙吗??

编辑: 这是我让用户在调用上述方法之前选择图片的方法

Intent choosePictureIntent = new Intent(Intent.ACTION_PICK, Images.Media.INTERNAL_CONTENT_URI);
tartActivityForResult(choosePictureIntent, REQUEST_CHOOSE_IMAGE);

这是OnActivityResult方法:

protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    if (resultCode == RESULT_OK) {
        switch (requestCode) {
        case REQUEST_CHOOSE_IMAGE:

            Uri selectedImage = intent.getData();

            try {

                int scale = CommonFunc.determineCorrectScale(this, selectedImage);

SDK中没有com.google.android.apps.photos.permission.GOOGLE_PHOTOS权限 - 即使API级别19的源代码也没有列出此权限。这可能是Google内部使用的某些权限。 - ChuongPham
2个回答

30

虽然在这个特定的内容提供程序中添加权限可以解决问题,但如果您的数据是由其他内容提供程序提供的,则不起作用(Android上没有保证您将通过特定内容提供程序获取数据,除非您显式访问该内容提供程序)。

此问题的“最终”解决方案可在此处找到:

使用临时权限获取访问

即使您没有适当的访问权限,也可以通过向具有权限的应用程序发送意图并接收包含“URI”权限的结果意图来访问内容提供程序中的数据。这些是特定内容URI的权限,其持续时间直到接收它们的活动完成

http://developer.android.com/guide/topics/providers/content-provider-basics.html

自4.3版本以来,Android会检查接收Activity是否仍在运行,如果不是则引发SecurityException。 determineCorrectScale是一个静态方法,因此我假设它至少有时在Activity生命周期外被调用。 要彻底解决此问题,您需要在Activity运行时从内容提供程序检索数据。我不知道您的应用程序的要求,但是如果没有涉及大量工作(例如从内容提供程序复制图像) ,则只需在UI线程上执行即可。如果需要大量工作,则使用由Activity启动的AsyncTask,但是然后您必须确保在检索到数据之前Activity不会结束(这可能有些棘手)。

我不仅添加了这个答案,因为我认为它是正确的,还因为其他开发人员可能不知道在4.3/4.4中引入的此更改,可能会遇到其他内容提供者的相同问题。


感谢您提供详细的答案。+1。我的应用程序要求是,在我的活动生命周期中,用户单击按钮从他的图库加载图片,一旦选择了图片,我获取URI并调用determineCorrectScale,以便对图片进行采样并将其加载到图像视图中(并将采样的图片复制到本地文件以便未来快速加载)。我仅使用以下内容提供程序getContentResolver().openInputStream。 - Snake
哦,还有静态方法,这样我就可以从任何地方调用它,但到目前为止,我只在活动内部调用它。 - Snake
你如何让用户从图库中选择一张图片?我猜你需要使用Intent启动某个活动?你能发一下那段代码吗?我问这个是因为在这种情况下,返回的URI取决于用户安装了哪些图库应用程序,因此内容提供程序也是任意的,这意味着添加该权限可能会修复特定内容提供程序的异常,但不适用于其他内容提供程序。 - Emanuel Moecklin
请检查我的编辑,查看我用来获取图像URI的代码。你有什么建议?这可能是新的可接受解决方案。 - Snake
使用您的意图来检索图像意味着您可以获取任意内容提供程序URI。通过接受的答案,您将能够解决此特定内容提供程序的问题,但不是一般性的。我尝试重现这个问题,但没有成功触发Google+图像提供程序,因此我不确定我的答案是否能解决这个问题。如果您知道触发Google+内容提供程序的方法(那个具有com.google.android.apps.photos.permission.GOOGLE_PHOTOS权限的提供程序),请告诉我,我会再试一次。 - Emanuel Moecklin
显示剩余3条评论

24

你需要在你的清单文件中添加这个权限:

<uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS"/>

希望这对您有用。请给我反馈。


3
好的,这是一项新的权限吗?我以前从未见过它。由于我没有4.3设备,所以无法重现,希望它能解决这个问题 :) - Snake
很高兴它对你有用。我曾经遇到过同样的错误,但当我阅读Google+是如何工作的时候,发现他们在他们的应用程序中使用了这个权限。看起来它被用于从您的手机获取照片,即使是已经存储在线的照片,比如在Google+中,但我还不确定!如果你发现了什么,请分享一下...为什么我会得到一个负评? - Coderji
1
抱歉给你点了踩。问题描述不够清晰,无法确定是否只会访问特定的内容提供者,或者可能会使用其他内容提供者,因此无法确定你的答案是否正确。根据Snake的反馈,我会考虑给你点赞(或者不点)。 - Emanuel Moecklin
只有那个内容提供者将被使用。 - Snake
2
非常感谢!当图像尚未下载时,似乎需要此权限。 - Ayyappa

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