简体   繁体   中英

Crash due to requiring READ_EXTERNAL_STORAGE permission even though it's in the Manifest

I've got the task of updating an Android application that was previously built with the following settings:

compileSdkVersion 19
buildToolsVersion '19.0.1'

defaultConfig {
    minSdkVersion 15
    targetSdkVersion 19
}

I downloaded the latest Android Studio and ended up changing these to the following to get the app to build:

compileSdkVersion 21
buildToolsVersion '21.1.2'

defaultConfig {
    minSdkVersion 15
    targetSdkVersion 19
}

The previously built app worked perfectly without any crash. Unfortunately when I build it now the app crashes with the following exception:

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

Even though the permission is clearly in the manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   package="com.dbotha.app">

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

The crash occurs at the point of loading a cursor for MediaStore.Images.Media.EXTERNAL_CONTENT_URI :

new CursorLoader(
                this,
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                new String[]{
                        MediaStore.Images.Media._ID,
                        MediaStore.Images.Media.BUCKET_ID,
                        MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
                        MediaStore.Images.Thumbnails._ID
                },
                null,
                null,
                null
        );

I'm a little bit stumped as to what to do beyond ripping the whole component out and reimplementing from scratch -- which I'd prefer to avoid ;)

It turns out that a project dependency had a maxSDKVersion attribute in the libraries in AndroidManifest.xml for these permissions:

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

During the manifest merge process that attribute would get included and break things on any device running above API version 18.

One approach to fixing this is to add the following applications manifest that will ensure the maxSdkVersion attributes don't make it into the merged AndroidManifest.xml :

<manifest
    xmlns:tools="http://schemas.android.com/tools"
    ...>

<uses-permission tools:node="replace" android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
<uses-permission tools:node="replace" android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="18" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM