Logo preload
close Logo

Fulcrum Android and Marshmallow Runtime Permissions

October 2, 2015

As most developers are probably aware, Google’s new update to the Android platform has officially been released! Android 6.0 Marshmallow will start rolling out to devices next week, with the Nexus devices getting the update first. So in the meantime, what is the new “Runtime Permissions” feature in Marshmallow?

Before Marshmallow, when installing an app on Android, users were prompted to view and accept the app’s “Install Permissions”.

Installation Permissions

Now, with Android 6.0 Marshmallow, comes “Runtime Permissions”, so called because the user agrees to them while the app is running. If you’ve ever used an iOS app, it’s similar to how the app will ask you to grant permission to the camera or photos while using the app instead of before installation. These changes make sense, but what I couldn’t find was: how does this affect my existing apps?

After spending quite a bit of time digging through Google’s documentation, I found the answers I needed:

If the device is running Android 6.0 (API level 23) or higher, and the app’s targetSdkVersion is 23 or higher, the app requests permissions from the user at run-time. The user can revoke the permissions at any time, so the app needs to check whether it has the permissions every time it runs.

If the device is running Android 5.1 (API level 22) or lower, or the app’s targetSdkVersion is 22 or lower, the system asks the user to grant the permissions when the user installs the app. If you add a new permission to an updated version of the app, the system asks the user to grant that permission when the user updates the app. Once the user installs the app, the only way they can revoke the permission is by uninstalling the app.

So essentially what this means is:

  1. Apps will run as they do now on Android 6.0, as long as they haven’t changed their targetSdkVersion to 23. On a 6.0 device with targetSdkVersion < 23, all permissions will still be accepted at installation time, meaning new application downloads won’t be affected.
  2. Devices with the application already installed won’t be affected because they’ve already accepted all the permissions needed to use the app.
  3. Don’t publish your app’s targetSdkVersion as 23 without first testing the app on an Android 6.0 device! (and on a device running less than 6.0 for that matter).

This got me thinking… what was it going to take to modify Fulcrum to work with the new permission scheme? So I took a look at the list of permissions Fulcrum currently requires in the AndroidManifest.xml. I was immediately a little confused; I had run the app on the 6.0 emulator, and it hadn’t crashed. Normally that’d be great news, but I was using INTERNET and ACCESS_WIFI_STATE and hadn’t granted those permissions… so why wasn’t the app crashing?

It turns out that permissions are separated into different protection levels. For the purposes of the “Runtime Permissions” upgrade, you only really have to concern yourself with NORMAL and DANGEROUS. The difference is outlined here, but basically what it comes down to is:

Dangerous permissions cover areas where the app wants data or resources that involve the user’s private information, or could potentially affect the user’s stored data or the operation of other apps.

At this point, the only thing I could do was assume things like INTERNET, ACCESS_WIFI_STATE, and WAKE_LOCK were NORMAL since I hadn’t been prompted for them… but you know what happens when you assume… So I kept looking and found this very useful page that outlines which permissions are NORMAL.

So when developers want to target API level 23, they’ll need to check that the application has been granted the permissions it needs for the actions it wants to take, BUT you only have to concern yourselves with DANGEROUS permissions. There’s a plethora of resources on how to make your permission changes (just google!), so I won’t go into detail here. I hope this post has helped you better understand how the “Runtime Permissions” feature will affect your app.