无法在我的项目中实施ACTION_OPEN_DOCUMENT

时间:2017-10-24 17:51:26

标签: java android

我有AddActivity,它允许您从相机拍摄的照片或可从照片库中选择的图像中获取URI。然后,您可以转到DetailsActivity查看图像。我现在正在使用它,直到你重启设备。重新启动并尝试转到该图像的DetailsActivity后,这是错误:

Caused by: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{3a5e86d 2915:jeremy.com.wineofmine/u0a321} (pid=2915, uid=10321) requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs

我访问了"Open Files Using Storage Access Framework" Android开发页面并阅读了持久权限部分。我虽然在将它应用到我的项目时遇到了麻烦。

我认为我不能理解的主要事情是你需要调用一个意图(在我的情况下是在DetailsActivity中),但我甚至没有意图。

这是让您选择图库图像的意图。这是在AddActivity中:

Intent intentGallery = new Intent(Intent.ACTION_OPEN_DOCUMENT);
            intentGallery.addCategory(Intent.CATEGORY_OPENABLE);
            intentGallery.setType("image/*");
            intentGallery.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intentGallery.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            startActivityForResult(intentGallery, SELECT_IMAGE);

在DetailsActivity中,这是它实际崩溃的地方:

imageURI = Uri.parse(cursor.getString(cursor.getColumnIndexOrThrow(WineContract.WineEntry.COLUMN_WINE_IMAGE)));

bitmap = null;
    try {
        //If the cursor does not have anything in the image column, set the image to null, with a height so the textviews look decent
        if (cursor.isNull(cursor.getColumnIndexOrThrow(WineContract.WineEntry.COLUMN_WINE_IMAGE))){
            mFullImage.setImageBitmap(null);
            mFullImage.setMaxHeight(300);
        }else{
            //remake the bitmap from the URI in the image column
      //********This next line is where the program crashes**********
            bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageURI);
            mFullImage.setImageBitmap(bitmap);

        }

我可以帮助找出如何将其应用到我的项目中吗?

3 个答案:

答案 0 :(得分:4)

supercall takePersistableUriPermission() on a ContentResolver中,传入与模式标志相关的onActivityResult(),指示您想要的访问权限(读取,写入,两者)。< / p>

答案 1 :(得分:2)

在onRequestPermissionsResult上处理权限结果,如下所示

 @Override
 public void onRequestPermissionsResult (int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case General.REQUESTPERMISSION:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //reload my activity with permission granted or use the features that required the permission

            } else {
                Messenger.makeToast(getContext(), R.string.noPermissionMarshmallow);
            }
            break;
    }
}

并在onActivityResult方法中保留权限工具,如下所示

@Override
public void onActivityResult (int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    //if ok user selected a file
    if (resultCode == RESULT_OK) {
        Uri sourceTreeUri = data.getData();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            getContext().getContentResolver().takePersistableUriPermission(sourceTreeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        }
    }
}

答案 2 :(得分:2)

有点晚,但是... 我们需要提供持久的Uri权限。我不想像先前的答案那样在onActivityResult上这样做,而是将其添加为标志:

val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).also {
    it.addCategory(Intent.CATEGORY_OPENABLE)
    it.type = "image/*"
    it.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
    it.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}

还有一个值得一提的注意事项,持久许​​可权仅适用于Intent.ACTION_OPEN_DOCUMENT不能 Intent.ACTION_GET_DOCUMENT,而后来的许可权只是一次。