19

I have two activities in my app, MainActivity calls ImagePicker, which has a GridView laying out all the images in the phone gallery, where I use a ContentResolver to get the cursor.

It worked fine on my phone when I tested it but crashed every time instantly on emulator.

Here's the error log:

java.lang.SecurityException: Permission Denial:reading com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=5934, uid=10060 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()

I do have permission written in manifest, as shown below:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity android:name=".ImagePicker" />
</application>
TPWang
  • 1,322
  • 4
  • 20
  • 39

3 Answers3

23

What version of android is your emulator? And are you compiling with SDK 23? If your emulator is Marshmallow, you need to explicitly check for the permission at runtime. This is due to the new permissions model.

Check out the docs on permissions for more info: https://developer.android.com/training/permissions/index.html

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
riggaroo
  • 2,584
  • 20
  • 34
17

Before calling method, check for permission.

private void checkPermission(){
    int permissionCheck = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE);

    if (permissionCheck != PackageManager.PERMISSION_GRANTED) {     
         ActivityCompat.requestPermissions(         
    getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Constants.WRITE_EXTERNAL_STORAGE); 
    } else {    
         callMethod(); 
    }
}

Check permission result.

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

            case Constants.WRITE_EXTERNAL_STORAGE:
                if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                    callMethod(); 
                }
                break;

            default:
                break;
        }
    }
ichthyocentaurs
  • 2,173
  • 21
  • 35
Philip Herbert
  • 4,599
  • 2
  • 37
  • 40
  • `Constants.WRITE_EXTERNAL_STORAGE` can be any int you want :) I replaced by my own constant in app-defined example: `static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 99;` – CGR Jun 28 '17 at 17:56
  • Use `android.Manifest.permission.WRITE_EXTERNAL_STORAGE` instead of `Manifest.permission.WRITE_EXTERNAL_STORAGE` – Souradeep Nanda May 27 '18 at 03:10
3

If your app target version is 23 then it will give you this error, if your requirement includes API level 23 then you need to make target 23 and need to check permissions dynamically here is the example from developer site check https://developer.android.com/training/permissions/requesting.html

Note: Even if you give target 22 or lower also your app will work with 23 without this(check permission) error.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Swamy
  • 132
  • 6