Runtime Permissions

In Android 6.0 Marshmallow, application will not be granted any permission at installation time. Instead, application has to ask user for a permission one-by-one at runtime.

The Permission request dialog  will not launch automatically. Developer has to call for it manually. In the case that developer try to call some function that requires a permission which user has not granted yet, the function will suddenly throw an Exception which will lead to the application crashing.

Besides, user is also able to revoke the granted permission anytime through phone's Settings application.

Runtime Permission will work like described only when we set the application's targetSdkVersion to 23 which mean it is declared that application has already been tested on API Level 23. And this feature will work only on Android 6.0 Marshmallow. The same app will run with same old behavior on pre-Marshmallow device.

If the application's targetSdkVersion is set to less than 23. It will be assumed that application is not tested with new permission system yet and will switch to the same old behavior: user has to accept every single permission at install time and they will be all granted once installed!  Anyway please note that user still can revoke a permission after that ! Although Android 6.0 warn the user when they try to do that but they can revoke anyway.

Automatically granted permissions

There is some permission that will be automatically granted at install time and will not be able to revoke. We call it Normal Permission (PROTECTION_NORMAL). Here is the full list of them:

  • android.permission.ACCESS_NETWORK_STATE
  • android.permission.ACCESS_NOTIFICATION_POLICY
  • android.permission.ACCESS_WIFI_STATE
  • android.permission.ACCESS_WIMAX_STATE
  • android.permission.BLUETOOTH
  • android.permission.BLUETOOTH_ADMIN
  • android.permission.BROADCAST_STICKY
  • android.permission.CHANGE_NETWORK_STATE
  • android.permission.CHANGE_WIFI_MULTICAST_STATE
  • android.permission.CHANGE_WIFI_STATE
  • android.permission.CHANGE_WIMAX_STATE
  • android.permission.DISABLE_KEYGUARD
  • android.permission.EXPAND_STATUS_BAR
  • android.permission.FLASHLIGHT
  • android.permission.GET_ACCOUNTS
  • android.permission.GET_PACKAGE_SIZE
  • android.permission.INTERNET
  • android.permission.KILL_BACKGROUND_PROCESSES
  • android.permission.MODIFY_AUDIO_SETTINGS
  • android.permission.NFC
  • android.permission.READ_SYNC_SETTINGS
  • android.permission.READ_SYNC_STATS
  • android.permission.RECEIVE_BOOT_COMPLETED
  • android.permission.REORDER_TASKS
  • android.permission.REQUEST_INSTALL_PACKAGES
  • android.permission.SET_TIME_ZONE
  • android.permission.SET_WALLPAPER
  • android.permission.SET_WALLPAPER_HINTS
  • android.permission.SUBSCRIBED_FEEDS_READ
  • android.permission.TRANSMIT_IR
  • android.permission.USE_FINGERPRINT
  • android.permission.VIBRATE
  • android.permission.WAKE_LOCK
  • android.permission.WRITE_SYNC_SETTINGS

Just simply declare those permissions in AndroidManifest.xml and it will work just fine. No need to check for the permission listed above since it couldn't be revoked.

Support new Runtime Permission

Now it's time to make our application support new Runtime Permission perfectly. Start with setting targetSdkVersion to 23 in AndroidManifest.xml.

First of all the Android Native allows you yo check if permission is already granted or not, see the sample bellow:

bool val = PermissionsManager.IsPermissionGranted(AN_MenifestPermission.WRITE_EXTERNAL_STORAGE);
if(val) {
  Debug.Log("WRITE_EXTERNAL_STORAGE Granted");
} else {

In case permissions isn't grandest yet, you may present the dialog asking user to grant certain permissions to your app. When dialog is completed ActionPermissionsRequestCompleted will be fired  after dialog completed. Code snipped can be found bellow:

PermissionsManager.ActionPermissionsRequestCompleted += HandleActionPermissionsRequestCompleted;
PermissionsManager.Instance.RequestPermissions(AN_MenifestPermission.WRITE_EXTERNAL_STORAGE, AN_MenifestPermission.CAMERA);

void HandleActionPermissionsRequestCompleted (AN_GrantPermissionsResult res) {
  foreach(KeyValuePair<AN_MenifestPermission, AN_PermissionState> pair in res.RequestedPermissionsState) {
    Debug.Log(pair.Key.GetFullName() + " / " + pair.Value.ToString());