Blog

Dangerous Permissions on Android Marshmallow

Starting from Android Marshmallow, version 6.0 of Android, there will be a change on how app permissions are handled. Users will gain more control over what permissions are granted to an app. Users no longer get to see a long list of permissions when they’re installing an app, but they grant the permission when the functionality is actually used. We think this will greatly improve the control users have over their apps and also we think it will be easier for app developers to introduce new features.


Don’t want to think about this? Get started with geofencing without a hassle!

Click Me


Android Marshmallow Mascot
At the moment an app specifies the permissions it wants in their AndroidManifest.xml and then when a user wants to install the app from the Google Play store a prompt appears asking whether the user want to grant the app all these permissions or not. When a user decides he doesn’t want to grant these permissions the complete installation is cancelled. Sometimes it is confusing upfront why an app needs a certain permission, because the user may not directly understand what you will use a certain permission for.

In the new situation the prompt when installing a new app in the Play Store is gone. Instead the app will no longer receive permissions that are considered “dangerous” directly after install, but the app has to ask the user to grant these permissions from inside the app the first time the user performs an operation which requires that permission. Examples of dangerous permissions are permissions that impact the users’ privacy such as access to their location or their contacts, or permissions that are related to actions that cost money such as telephony and SMS. Permissions that aren’t dangerous are granted right away, so the user no longer has to consider those permissions. This way the more dangerous stand out and users now also have the possibility to use an app without granting some of these dangerous app permissions.

 

First opt-in dialog

First opt-in dialog

Of course old apps don’t have the logic yet that is needed to request those permissions, therefore old apps will continue to work the old way, even when running on Android Marshmallow. Also apps designed for Marshmallow handle the permissions the old way when running on older Android versions, such as Lollipop and KitKat, so your new apps also will work there. When a device is upgraded from Lollipop to Marshmallow the granted dangerous permissions are remembered, so asking for permissions is not required for those apps.

In Android Marshmallow users have the possibility to change the access of apps to these dangerous features anytime. When they grant or deny a permission in the system dialog inside the app, they can change it later if they change their mind. We don’t think a lot of users will make use of this, since users have to go some menu levels deep to get to the screen where the permissions can be changed, but it will be possible. Revoking of dangerous permissions through the settings menu is also possible for older apps who aren’t designed for Marshmallow.

 

App permissions

App Permissions

Introducing a new permissions no longer stalls auto updates when the device is running on Android Marshmallow, so introducing features depending on such functionality has become easier. When the newly added permission isn’t considered dangerous, the app is granted the permission straight away, else it will work the same as the other dangerous permissions. You have to ask the user at the time you’re using the feature. This is a great improvement, since introducing a new permission caused a large group of your users to stay behind on an older version. This will luckily no longer be the case.

What do I have to do to make my app compatible?

We have seen what is changed, now how do I get my app ready for the Marshmallow way of dealing with notifications? The first thing you have to do is telling Android that you’re targeting the latest API level. You do so by setting targetSdkVersion to 23 in your AndroidManifest.xml. With the targetSdkVersion set to 23 dangerous permissions will no longer be granted during installation, but you have to request them at first usage. You still have to add the permissions to your AndroidManifest.xml.

So how do I ask for permission then? In Android API level 23 a new method is added to the Activity class: Activity.requestPermissions(permissions, requestCode). Calling this method pops up a system dialog which allows the user to decide whether or not he wants to grant the permission. The second time this method is called for the same permission a “Never show again” option is added to the dialog. When checked by the user, the dialog will no longer appear in the future for that permission. To make it easier to target earlier Android API levels, this method is also available in the support-v4 library. The method in the support library, ActivityCompat.requestPermissions(activity, permissions), works on all API levels from 4. Calling this method on Marshmallow will show the dialog, while on earlier platform it doesn’t perform an action.

 

Second opt-in dialog

Second opt-in dialog

This is an example snippet showing how to request a permission when it hasn’t been granted:

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
  final String[] permissions = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
  ActivityCompat.requestPermissions(this, permissions, 0);
}

Some users may decide that they don’t want to grant your app this permission at first. It is possible to provide some extra information when you ask the user again for their permission. The function that tells you whether the user has denied the request before is: Activity.shouldShowRequestPermissionRationale(permission), which requires API level 23 as well, or the ActivityCompat.shouldShowRequestPermissionRationale(activity, permission) from the compat library.

An example that uses this feature is here:

final String[] permissions = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
  if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage("To receive relevant location based notifications you have to allow us access to your location.");
    builder.setTitle("Location Services");
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
        ActivityCompat.requestPermissions(MainActivity.this, permissions, 0);
      }
    });

    builder.show();
  } else {
    ActivityCompat.requestPermissions(this, permissions, 0);
  }
}

Of course the user may decide in the end not to grant you the permission. You have to make sure your app continues to work without that permission. Before you use a feature that requires a dangerous permission, first check the user granted you that permission. If you don’t check it, it is possible your app will crash, which will make your app look bad.

You can easily test whether your permission logic works correctly in the emulator. Emulator images for Marshmallow are already available. Don’t forget to test that your app continues to work correctly when the user doesn’t grant your app the permission.

 

Permissions for an app

Permissions for an app

If you’re not quite ready to make these changes to your app, it is possible to keep the old behaviour by setting the targetSdkVersion to a version lower than 23. When setting it to an API level below 23, the Play Store will continue to ask for all the permissions upfront when the app is installed. Something you have to keep in mind is that users have the power to revoke permissions later, even apps not targeting API level 23, so your app should continue to work without certain permissions.

And what will Plot Projects do?

The dangerous permission our plugin requires is access to location. Without the location of the device it will of course be impossible to send relevant location based notifications. Because the method to request a permission is placed in the Activity class, we’ve added an overload to our Plot.init method that accepts an Activity. When you use that method we will automatically request permission for the usage of location data.

It is also possible to ask for the permission yourself if you want more control of over this process. If you don’t use the init overload which accepts an Activity or if you wait with calling Plot.init until the user grants the permission then you are in full control when the dialog appears. A use case for this would be when you want to ask for multiple permissions at the same time. Another use case for this would be when you want to provide a rationale when the user denies the permission the first time.

Wrap up

We’ve looked at the new way Android will deal with permissions when Marshmallow is released. Users get more control over what permissions are granted to their installed apps because they explicitly have to opt-in, and usage of new permissions will no longer cause problems with automatic updates because the opt-in is postponed until the feature is actually used.

We are definitely looking forward to Android Marshmallow. Improved permissions, Doze mode to save battery when the device is stationary and idle, app links, …. All great features. With no official release yet, we still have to wait a bit. But it is good to be prepared for these changes.

More information:
Android Runtime Permissions
Google I/O 2015 – Android M Permissions


Don’t want to think about this? Get started with geofencing without a hassle!

Click Me

Spread the love