Runtime Permissions – Android Marshmallow Tutorial

Runtime Permissions is a new permission model introduced in Android Marshmallow 6.0. Users are able to grant permissions during the app’s runtime, rather than during app install. Let’s look at leveraging the new runtime permissions for Android Marshmallow.

The Runtime Permission Model

As always, lets first see what good it does. The new permission model allows users to take control of permissions and decide what to grant when. This can be controlled from the App Info > App permissions section.

runtime-permissions-list

App permissions list

 Good for users, not for developers

In pre Marshmallow, all permissions had to be granted during install time. An app at any point of time had access to ALL permissions it requested. The user had no choice but to accept them. But that has changed now. Runtime permissions give users control over the sensitive information they provide. They chose which apps can access what, and when they cannot.

While this is good news for users, for a developer, it is not. Earlier we simply declared permissions in AndroidManifest.xml and we were on our way. But now apart from that, we need to check every time for a permission related task. Such as requesting the camera, calendar, contacts and so on. In addition, if the user denies the request permission, we need to handle that too.

Phew! That’s a lot of checking.

You may wonder, “If I’m using the new permission model, what about pre Marshmallow devices?”. Thankfully, implementing this gracefully falls back to the previous permission model on older devices. Great! That’s one less to worry about.

Guidelines

Runtime permissions add a new dimension to your app’s user experience. As an Android developer, you need to know WHEN and HOW to ask users for one, without annoying them.

Design patterns for runtime permissions.


Getting Started

If there’s one way to lessen our worries, its using a library. Like this one. The Permission Helper library will help us implement runtime permissions a whole lot easier!

Start by adding the library to your apps’ build.gradle file:

compile 'com.github.k0shk0sh:PermissionHelper:1.0.7'

Normal and Dangerous Permissions

That’s how Android’s permissions are categorized into two groups. The full list is here.

Cover areas where your app needs to access data or resources outside the app’s sandbox, but where there’s very little risk to the user’s privacy  – Normal Permissions

Dangerous permissions cover areas where the app wants data or resources that involve the user’s private information – Dangerous Permissions

Android will automatically grant access for Normal Permissions. So runtime permissions really come into play for the Dangerous Permissions.


Requesting Runtime Permissions

I’m going to request the ‘dangerous’ permission of reading the calendar. So for reference sake, I declare it like this:

final String PERMISSION = Manifest.permission.READ_CALENDAR;

Let’s bring the library’s magic into play. Implement OnPermissionCallback in your Activity. You’ll get the following methods:

  1. onPermissionGranted() – permission requested, and successfully granted by user
  2. onPermissionDeclined() – permission requested, but declined by user
  3. onPermissionPreGranted() – requested permission is already granted (allowed via app permissions screen)
  4. onPermissionNeedExplanation() – requested permission was denied, tell the user why you need it
  5. onPermissionReallyDeclined() – requested permission was denied, and future requests were denied too. ( Can only be allowed from Settings now)
  6. onNoPermissionNeeded() – fallback method for pre Marshmallow devices (older permissions model)

Firstly, initialize your PermissionsHelper:

permissionHelper = PermissionHelper.getInstance(this);

Then request your permission, say in your button’s OnClickListener.

permissionHelper.setForceAccepting(false).request(PERMISSION);

setForceAccepting() helps ensure that the request doesn’t force the user to grant permission.

How to start an App Business in less than a week with zero app development. APPPortunity Coaching Program - Enroll now for an insane 98% discount!

Next, override the Activity’s onRequestPermissionsResult() method.

@Override
   public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
       permissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults);

   }

 Handling Requested Permission

After requesting the permission, we need to handle:

  1. Permission grant
  2. Permission denial

runtime permissions user flow

1. Permission Grant

Override the Activity’s onRequestPermissionsResult()

@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

        permissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults);

    }

If the user granted permission, then onPermissionGranted() is used, otherwise onPermissionDeclined() is called.

In the user flow diagram, you can see that a denied permission can be requested again. If requested again, this time a system dialog doesn’t appear. But the permission will be added to your app’s Permissions screen, from where you can manually enable disable requested permissions.

runtime permissions system dialo

System dialog shown first time

system dialog with checkbox

System dialog after first time

So if you want to request a denied permission, use the onPermissionNeedExplanation() method. Use this to tell the user WHY you need that permission. I do it with a simple dialog explaining why.

AlertDialog dialog = new AlertDialog.Builder(this)
          .setTitle(title)
          .setMessage(message)
          .setPositiveButton("Request", new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int which) {

                  permissionHelper.requestAfterExplanation(permission);

              }
          })
          .create();

  dialog.show();

Finally, if you’re requesting for a permission that is already granted, then the onPermissionPreGranted() method comes really handy.

2. Permission Denial

Now what if the user denied permission? You need to handle that too. Since I’m requesting to read the calendar, if the user refuses to grant my request, I need a contingency plan.

You can handle denial with the onPermissionDeclined() method.

See the system dialog above, on the right? If the user checks ‘Never ask again‘, then that permission can ONLY be enabled via the app’s permissions screen found here:

app-info-settings

runtime-permissions-list

You can handle this condition using the onPermissionReallyDeclined() method.

Fallback

Like I mentioned earlier. Devices running pre Marshmallow reverts to using the older permission model. This is automatically managed, since permissions are defined in AndroidManifest.xml. One less worry for us. Cheers!


Final Output

With everything in it’s place, let’s finally run our app and watch Runtime Permissions in action! In my demo, I’ve printed logs to a TextView. This way, you can see which methods are called when.

Source code on GitHub.

That’s all for this post. I hope runtime permissions with Android Marshmallow is clear now. Especially thanks to the Permission Helper library.

If this post helped you handle runtime permissions like a pro, considering sharing so others can benefit too.

Cheers!

App developer with an eye for design. Loves to create apps with good UI/ UX that doesn’t annoy people. In his spare time, he likes to draw and paint.

Enjoyed this article? Please spread the word.

Subscribe to Newsletter
Be the first to get latest updates and exclusive content
straight to your email inbox.
STAY UPDATED
Chill, I hate spam too. You can unsubscribe anytime.

Top Recommended Books by StackOverflow Users

Suleiman

App developer with an eye for design. Loves to create apps with good UI/ UX that doesn't annoy people. In his spare time, he likes to draw and paint.

You may also like...

Enjoyed this article? Please spread the word.

Subscribe to Newsletter
Be the first to get latest updates and exclusive content
straight to your email inbox.
STAY UPDATED
Chill, I hate spam too. You can unsubscribe anytime.

Gradle setup, ProGuard rules, Material Design palette, metrics and much more

FREE Material Design Starter Project

For more details, click on the below link.
GET IT NOW FOR ANDROID STUDIO!
Download FREE
STARTER PROJECT
Material Design Template Project for Android Studio
DOWNLOAD STARTER PROJECT
Develop faster with a multi-purpose, ready to use App
GET THE CODE