【问题标题】:Permission for an image from Gallery is lost after re-launch重新启动后,图库中的图像的权限丢失
【发布时间】:2017-10-17 07:56:51
【问题描述】:

我的应用程序允许用户从图库或其他位置查看一些选定的图像。我通过以下方式请求 Uri 的图像:

Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, PickerFragment.PICK_PHOTO);

然后在 onActivityResult (int requestCode, int resultCode, Intent data) 中获取 Uri 并通过以下方式访问这些图像以将它们放在我的应用的视图中:

Uri imageUri= data.getData();

应用完成后,我将数据库中的所有 Uri 保存为字符串:

String imageUriString = imageUri.toString();
saveToDB (imageUriString);

但是,当我重新启动应用程序并通过以下方式从我的数据库中恢复所有 Uri 时:

String imageUriString = restoreFromDB ();
imageUri = Uri.parse (imageUriString);

在 Android 7.1 中,该应用不再拥有这些 Uri 的权限。 我正在通过以下方式访问图像:

ContentResolver cr = mContext.getContentResolver();
InputStream is = cr.openInputStream(imageUri);
BitmapFactory.decodeStream(is, null, o);

但收到此异常:

java.lang.SecurityException: Permission Denial: opening provider com.google.android.apps.photos.contentprovider.impl.MediaContentProvider from ProcessRecord

是否有一种优雅且合法的方式来保留该权限? 我试图阅读所有有关权限的文档,但感到非常困惑。

如果您能告诉我正确的学习方向,将不胜感激。

PS 在 Uri 的许可持续期间将图像复制到应用程序内存是一种选择,但我想避免这种情况。至少看看有没有可能。

PPS 我已授予所有权限,例如相机和外部存储写入和读取。

【问题讨论】:

  • 存储 byteArray 而不是 uri。当图库中不存在图像时,Uri 失败。
  • @Anonymous,存储是一种选择,但不可取。在我的情况下,即使图像 出现在图库中,Uri 也会失败
  • 确实很奇怪,因为据我所知 ACTION_PICK 没有权限标志。早些时候,只有 ACTION_GET_CONTENT 受此影响。但我可以确认你的问题。更改为 ACTION_GET_CONTENT 无济于事,因为您无法使权限保持不变。
  • 未经测试:使用 ACTION_OPEN_DOCUMENT。未经测试。请尝试报告。

标签: android image permissions gallery


【解决方案1】:

因此,在@greenapps 的大力帮助下,在模拟器和真实设备上进行测试后,解决方案如下:

  • 使用另一个意图:

    意图 photoPickerIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);

  • 在 onActivityResult() 中确保 Uri 的持久权限在应用重新启动后将保持不变:

    Uri selectedImage = data.getData();

    如果(Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2){ getContentResolver().takePersistableUriPermission (selectedImage, Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_GRANT_WRITE_URI_PERMISSION); }

【讨论】:

  • 还有两件事需要担心:首先,如果您将 URI 作为 Activity 状态的一部分进行持久化,则应在尝试加载之前检查 URI 是否仍然有效(请参阅@987654321 @)。其次,当您确定已完成 URI 时,您应该使用 ContentResolver.releasePersistableUriPermission() 撤销您的许可。最后,虽然此逻辑适用于 Intent.ACTION_OPEN_DOCUMENT,但如果您的应用收到 Intent.ACTION_SEND 或 Intent.ACTION_SEND_MULTIPLE,则它不起作用。
【解决方案2】:

参考答案here

使用以下代码打开一个对话框:

 ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                    1);

获取Activity结果如下:

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 1: {

          // If request is cancelled, the result arrays are empty.
          if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.          
            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
                Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

更多信息:https://developer.android.com/training/permissions/requesting.html

【讨论】:

  • 我已授予所有权限,例如相机和外部存储写入和读取。我的问题是关于另一个问题。
  • 问题在于文件 Uri 权限,而不是一般的运行时权限。
猜你喜欢
  • 1970-01-01
  • 2012-10-20
  • 2013-01-22
  • 1970-01-01
  • 2014-07-01
  • 1970-01-01
  • 2015-09-17
  • 2012-12-05
  • 1970-01-01
相关资源
最近更新 更多