Hey, Where Did My Permission Go?

Some developers wonder where extra permissions in their app come from.

Other developers wonder why they are not getting the permissions that they are asking for. If you have a <uses-permission> element, and you are encountering SecurityExceptions or other symptoms that suggest that you do not actually hold the permission that you asked for, there are a few possible culprits.

You Have the Element in the Wrong Place

The <uses-permission> elements should be inside the <manifest> element, but outside the <application> element. In other words, this is fine:

<?xml version="1.0" encoding="utf-8"?> <manifest package="com.commonsware.android.something.something" xmlns:android="http://schemas.android.com/apk/res/android"> <uses-permission android:name="INTERNET"/> <uses-permission android:name="ACCESS_NETWORK_STATE"/> <application android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"> <!-- cool stuff goes here --> </application> </manifest>

but this is not:

<?xml version="1.0" encoding="utf-8"?> <manifest package="com.commonsware.android.something.something" xmlns:android="http://schemas.android.com/apk/res/android"> <application android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"> <uses-permission android:name="INTERNET"/> <uses-permission android:name="ACCESS_NETWORK_STATE"/> <!-- cool stuff goes here --> </application> </manifest>

While Android Studio will report this if you manually analyze your manifest (Analyze > Inspect Code… from the main menu), it will not automatically show a warning just by having the elements in the wrong spot.

You Cannot Hold That Permission

Some permissions that used to be in the Android SDK, such as BRICK , cannot be held by ordinary Android applications. They usually require your app to be signed by the signing key that signed the device firmware (i.e., be part of a custom ROM). Some might alternatively allow your app to hold the permission if your app is installed on the /system partition (i.e., be part of a custom ROM or have been moved there by a rooted device user).

However, you are not told at build time that the <uses-permission> element you have in your manifest is tied to a permission that you are unlikely to be able to hold.

Your targetSdkVersion Is 23 or Higher

The big reason for not getting your permission nowadays is because your project has a targetSdkVersion of 23 or higher, and the permission that you are requesting is “dangerous”. In Android 6.0, this includes:

ACCESS_COARSE_LOCATION

ACCESS_FINE_LOCATION

ADD_VOICEMAIL

BODY_SENSORS

CALL_PHONE

CAMERA

GET_ACCOUNTS

PROCESS_OUTGOING_CALLS

READ_CALENDAR

READ_CALL_LOG

READ_CELL_BROADCASTS

READ_CONTACTS

READ_EXTERNAL_STORAGE

READ_PHONE_STATE

READ_SMS

RECEIVE_MMS

RECEIVE_SMS

RECEIVE_WAP_PUSH

RECORD_AUDIO

SEND_SMS

USE_SIP

WRITE_CALENDAR

WRITE_CALL_LOG

WRITE_CONTACTS

WRITE_EXTERNAL_STORAGE

For these permissions, not only does your targetSdkVersion 23+ app need to have the <uses-permission> element(s), but you also have to ask for those permissions at runtime from the user on Android 6.0+ devices, using methods like checkSelfPermission() and requestPermissions() .

As a temporary workaround, drop your targetSdkVersion below 23.

However, eventually, you will have some reason to want your targetSdkVersion to be 23 or higher. At that time, you will need to adjust your app to use the new runtime permission system. The Android 6.0 preview documentation has a page dedicated to this topic, and my book has a lot of material on how to make this work in your app.

The AndroidX Tech site contains source code, transitive dependency details, and much more for Google’s androidx artifacts!

— Aug 31, 2015