3

I use the following code to convert Bitmap to 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);
}

But, when I run the code , the following exception occurs:

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)

I have already added the <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" to the manifest and enabled the Storage Permission in App Settings. How can I implement this grantUriPermission() in the app?

Jayesh Babu
  • 1,389
  • 2
  • 20
  • 34

3 Answers3

1

If your app needs a dangerous permission, you must check whether you have that permission every time you perform an operation that requires that permission. Beginning with Android 6.0 (API level 23), users can revoke permissions from any app at any time, even if the app targets a lower API level. So even if the app used the camera yesterday, it can't assume it still has that permission today.

To check if you have a permission, call the ContextCompat.checkSelfPermission() method. For example, this snippet shows how to check if the activity has permission to write to the calendar

if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)
    != PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
}

For example

picking an image from media

  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
        )
    }
    }

reference

Praveen
  • 946
  • 6
  • 14
  • The `Storage` permission in App Settings is enabled. Doesn't automatically enable READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE ? – Jayesh Babu Jun 11 '19 at 06:58
  • 1
    if you already granted permission then just check whether you have that permission every time you perform an operation – Praveen Jun 11 '19 at 07:12
1

Here is example of runtime permission.

This is example for both CAMERA and WRITE_EXTERNAL_STORAGE.

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 is ArrayList for check which permissions are granted or not in case of multiple permission

Chirag Savsani
  • 6,020
  • 4
  • 38
  • 74
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;
        }
    }

Use this in activity

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);
        }
    }

To show dialog :

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();
    }
Karan Khurana
  • 575
  • 8
  • 20