无法将位图转换为Uri。

3

我使用以下代码将Bitmap转换为Uri

public Uri GetImageUriFunction(Context inContext, Bitmap inImage)
{
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
    String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
    return Uri.parse(path);
}

但是,当我运行代码时,出现了以下异常:

java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=12433, uid=10438 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()
    at android.os.Parcel.createException(Parcel.java:1966)
    at android.os.Parcel.readException(Parcel.java:1934)
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
    at android.content.ContentProviderProxy.insert(ContentProviderNative.java:476)
    at android.content.ContentResolver.insert(ContentResolver.java:1593)
    at android.provider.MediaStore$Images$Media.insertImage(MediaStore.java:1014)

我已经在清单文件中添加了<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE",并且在应用设置中启用了存储权限。我该如何在应用程序中实现这个grantUriPermission()


你添加了运行时权限吗? - Praveen
没有,我没有。 - Jayesh Babu
1
请查看这个链接,它是你问题的答案:https://dev59.com/SJDea4cB1Zd3GeqPaVhV#33278500 - Ikazuchi
可能是重复的问题 (https://dev59.com/SJDea4cB1Zd3GeqPaVhV#33278500) - Prachi Singh
3个回答

1
如果您的应用程序需要危险权限,则必须在每次执行需要该权限的操作时检查是否具有该权限。从Android 6.0(API级别23)开始,用户可以随时撤销任何应用程序的权限,即使该应用程序针对较低的API级别。因此,即使应用程序昨天使用了相机,它也不能假设今天仍然具有该权限。
要检查是否具有权限,请调用ContextCompat.checkSelfPermission()方法。例如,以下代码片段显示如何检查活动是否具有写入日历的权限。
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)
    != PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
}

例如,从媒体库中选择图像。
  private fun pickImage() {
    if (ActivityCompat.checkSelfPermission(
            this,
            READ_EXTERNAL_STORAGE
        ) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
            this,
            WRITE_EXTERNAL_STORAGE
        ) == PackageManager.PERMISSION_GRANTED
    ) {
        val i = Intent(
            Intent.ACTION_PICK,
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI
        )
        startActivityForResult(i, PICK_IMAGE_REQUEST_CODE)

    } else {
        ActivityCompat.requestPermissions(
            this,
            arrayOf(READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE),
            READ_EXTERNAL_STORAGE_REQUEST_CODE
        )
    }
    }

参考


App设置中的“存储”权限已启用。这难道不会自动启用READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE吗? - Jayesh Babu
1
如果您已经授予权限,则每次执行操作时只需检查是否具有该权限。 - Praveen

1

这是运行时权限的示例。

这是相机和写入外部存储权限的示例。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    int hasPermissionCamera = checkSelfPermission(Manifest.permission.CAMERA);
                    int hasPermissionStorage = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
                    if (hasPermissionCamera != PackageManager.PERMISSION_GRANTED || hasPermissionStorage != PackageManager.PERMISSION_GRANTED) {
                        if (!addPermission(permissionsList, Manifest.permission.CAMERA))
                            permissionsNeeded.add("Camera");
                        if (!addPermission(permissionsList, Manifest.permission.WRITE_EXTERNAL_STORAGE))
                            permissionsNeeded.add("Read External Storage");

                        if (permissionsList.size() > 0) {
                            if (permissionsNeeded.size() > 0) {
                                String message = "You need to allow " + permissionsNeeded.get(0);
                                for (int i = 1; i < permissionsNeeded.size(); i++)
                                    message = message + ", " + permissionsNeeded.get(i);

                                message = message + " permissions for add image.";
                                showMessageOKCancel(message,
                                        new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                                                        REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);

                                            }
                                        });
                                return;
                            }
                            requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                                    REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
                            return;
                        }
                    }
                }

permissionsNeeded是ArrayList,用于检查多个权限是否已授予。


1
public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1;

public boolean checkPermission(
            final Context context) {
        int currentAPIVersion = Build.VERSION.SDK_INT;
        if (currentAPIVersion >= android.os.Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(context,
                    Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(
                        (Activity) context,
                        Manifest.permission.READ_EXTERNAL_STORAGE)) {
                    showDialog("storage", context,
                            Manifest.permission.READ_EXTERNAL_STORAGE);

                } else {
                    ActivityCompat
                            .requestPermissions(
                                    (Activity) context,
                                    new String[] { Manifest.permission.READ_EXTERNAL_STORAGE },
                                    MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
                }
                return false;
            } else {
                return true;
            }

        } else {
            return true;
        }
    }

在活动中使用此代码。
if (checkPermissionREAD_EXTERNAL_STORAGE(this)) {
            // do your stuff..
        }

onRequestPermissionsResult

@Override
    public void onRequestPermissionsResult(int requestCode,
            String[] permissions, int[] grantResults) {
        switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // do your stuff
            } else {
                Toast.makeText(Login.this, "GET_ACCOUNTS Denied",
                        Toast.LENGTH_SHORT).show();
            }
            break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions,
                    grantResults);
        }
    }

显示对话框:

public void showDialog(final String msg, final Context context,
            final String permission) {
        AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
        alertBuilder.setCancelable(true);
        alertBuilder.setTitle("Permission necessary");
        alertBuilder.setMessage(msg + " permission is necessary");
        alertBuilder.setPositiveButton(android.R.string.yes,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions((Activity) context,
                                new String[] { permission },
                                MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
                    }
                });
        AlertDialog alert = alertBuilder.create();
        alert.show();
    }

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