29
1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory http://inthecheesefactory.com/blog/thingsyouneedtoknowaboutandroidmpermissiondeveloperedition/en 1/29 Everything every Android Developer must know about new Android's Runtime Permission Posted on 26 Aug 2015 05:16 | 57137 reads | 298 shares (/blog/things-you-need-to-know-about-android-m- permission-developer-edition/en) (/blog/things-you-need-to- know-about-android-m-permission-developer-edition/th) Android M's name was just announced officially days ago. The final version is almost there and would be released not so long. Although Android is being keep developed but the latest update to Android M is totally different since there is some major change that would change everything like new Runtime Permission. Surprisingly it is not much talked about in Android Developer community even though it is extremely important and may cause some big trouble in the near future. That's the reason why I decide to blog about this topic today. Everything you need to know about this new Runtime Permission including how to implement it in your code. Let's do it before it's too late. The New Runtime Permission

Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

Embed Size (px)

DESCRIPTION

Android Permissions

Citation preview

Page 1: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 1/29

Everything every AndroidDeveloper must know about newAndroid's Runtime PermissionPosted on 26 Aug 2015 05:16 | 57137 reads | 298 shares 

(/blog/things-you-need-to-know-about-android-m-

permission-developer-edition/en) (/blog/things-you-need-to-

know-about-android-m-permission-developer-edition/th)

Android M's name was just announced officially days ago. The finalversion is almost there and would be released not so long.

Although Android is being keep developed but the latest update toAndroid M is totally different since there is some major change thatwould change everything like new Runtime Permission. Surprisinglyit is not much talked about in Android Developer community eventhough it is extremely important and may cause some big trouble inthe near future.

That's the reason why I decide to blog about this topic today.Everything you need to know about this new Runtime Permissionincluding how to implement it in your code. Let's do it before it's toolate.

The New Runtime Permission

Page 2: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 2/29

The New Runtime PermissionAndroid's permission system is one of the biggest security concernall along since those permissions are asked for at install time. Onceinstalled, the application will be able to access all of things grantedwithout any user's acknowledgement what exactly application doeswith the permission.

No surprise why there are so many bad guys trying to collect user'spersonal data through this security weakness and use it in the badway.

Android team also know this concern. 7 year passed, finallypermission system is redesigned. In Android 6.0 Marshmallow,application will not be granted any permission at installationtime. Instead, application has to ask user for a permission one-by-one at runtime.

Page 3: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 3/29

Please note that permission request dialog shown above willnot launch automatically. Developer has to call for it manually. In thecase that developer try to call some function that requires apermission which user has not granted yet, the function willsuddenly throw an Exception which will lead to the applicationcrashing.

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

Page 4: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 4/29

You might already feel like there is some cold wind blowing throughyour arms ... If you are an Android Developer, you will suddenlyknow that programming logic is totally changed. You cannot just calla function to do the job like previous but you have to check for thepermission for every single feature or your application will justsimply crash !

Correct. I would not spoil you that it is easy. Although it is a greatthing for user but it is truly nightmare for us developer. We have totake coding to the next level or it will surely have a problem in bothshort-term and long-term.

Page 5: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 5/29

Anyway this new Runtime Permission will work like described onlywhen we set the application's targetSdkVersion to 23 which mean itis declared that application has already been tested on API Level 23.And this feature will work only on Android 6.0 Marshmallow. Thesame app will run with same old behavior on pre-Marshmallowdevice.

What happened to the applicationthat has already been launched?This new permission system may cause you some panic right now."Hey ! What's about my application that launched 3 years ago. Ifit is installed on Android 6.0 device, does this behavior alsoapplied? Will my application also crash?!?"

Don't worry. Android team has already thought about it. If theapplication's targetSdkVersion is set to less than 23. It will beassumed that application is not tested with new permissionsystem yet and will switch to the same old behavior: user has toaccept every single permission at install time and they will beall granted once installed !

Page 6: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 6/29

As a result, application will run perfectly like previous.Anyway please note that user still can revoke a permission afterthat ! Although Android 6.0 warn the user when they try to do thatbut they can revoke anyway.

Page 7: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 7/29

Next question in your head right now. So will my application crash?

Such a kindness sent from god delivered through the Android team.When we call a function that requires a permission user revoked onapplication with targetSdkVersion less than 23, no any Exception willbe thrown. Instead it will just simply do nothing. For the function thatreturn value, it will return either null or 0 depends on the case.

Page 8: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 8/29

But don't be too happy. Although application would not be crashedfrom calling a function. It may still can crash from what thatapplication does next with those returned value.

Good news (at least for now) is these cases may rarely occur sincethis permission revoking feature is quite new and I believe that justfew user will do it. In case they do, they have to accept the result.

But in the long run, I believe that there will be millions of userswho turn some permission off. Letting our application not towork perfectly on new device is not acceptable.

To make it work perfectly, you better modify your application tosupport this new permission system and I suggest you to start doingit right now !

For that application which source code is not successfully modifiedto support Runtime Permission, DO NOT release it withtargetSdkVersion 23 or it will cause you a trouble. Move thetargetSdkVersion to 23 only when you pass all the test.

Page 9: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 9/29

Warning: Right now when you create a new project in Android Studio.targetSdkVersion will be automatically set to the latest version, 23. If youare not ready to make your application fully support the RuntimePermission, I suggest you to step down the targetSdkVersion to 22 first.

Automatically granted permissionsThere is some permission that will be automatically granted at installtime and will not be able to revoke. We call it Normal Permission(https://developer.android.com/preview/features/runtime-permissions.html#normal) (PROTECTION_NORMAL). Here is the fulllist of them:

android.permission.ACCESS_LOCATION_EXTRA_COMMANDS 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

Page 10: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 10/29

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 com.android.alarm.permission.SET_ALARM com.android.launcher.permission.INSTALL_SHORTCUT com.android.launcher.permission.UNINSTALL_SHORTCUT

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

Make your application support newRuntime PermissionNow it's time to make our application support new RuntimePermission perfectly. Start with settingcompileSdkVersion  and  targetSdkVersion  to 23.

Page 11: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 11/29

In this example, we try to add a contact with a function below.

The above code requires WRITE_CONTACTS permission. If it is calledwithout this permission granted, application will suddenly crash.

123456789

android {    compileSdkVersion 23    ...     defaultConfig {        ...        targetSdkVersion 23        ...    }

12345678910111213141516171819202122232425262728293031

private static final String TAG = "Contacts";private void insertDummyContact() {    // Two operations are needed to insert a new contact.    ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(     // First, set up a new raw contact.    ContentProviderOperation.Builder op =            ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)                    .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE,                     .withValue(ContactsContract.RawContacts.ACCOUNT_NAME,     operations.add(op.build());     // Next, set the name for the contact.    op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID,             .withValue(ContactsContract.Data.MIMETYPE,                    ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)            .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,                    "__DUMMY CONTACT from runtime permissions sample"    operations.add(op.build());     // Apply the operations.    ContentResolver resolver = getContentResolver();    try {        resolver.applyBatch(ContactsContract.AUTHORITY, operations);    } catch (RemoteException e) {        Log.d(TAG, "Could not add a new contact: " + e.getMessage());    } catch (OperationApplicationException e) {        Log.d(TAG, "Could not add a new contact: " + e.getMessage());    }}

Page 12: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 12/29

Next step is to add a permission into  AndroidManifest.xml  withsame old method.

Next step is we have to create another function to checkthat permission is granted or not. If it isn't then call a dialog to askuser for a permission. Otherwise, you can go on the next step,creating a new contact.

Permissions are grouped into Permission Group like table below.

1 <uses‐permission android:name="android.permission.WRITE_CONTACTS"/>

Page 13: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 13/29

If any permission in a Permission Group is granted. Anotherpermission in the same group will be automatically granted as well.In this case, once WRITE_CONTACTS is granted, application will alsogrant READ_CONTACTS and GET_ACCOUNTS .

Page 14: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 14/29

Source code used to check and ask for permission is Activity'scheckSelfPermission and requestPermissions respectively. Thesemethods are added in API Level 23.

If permission has already been granted, insertDummyContact() willbe suddenly called. Otherwise, requestPermissions will be called tolaunch a permission request dialog like below.

1234567891011

final private int REQUEST_CODE_ASK_PERMISSIONS = 123; private void insertDummyContactWrapper() {    int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS);    if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {        requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},                REQUEST_CODE_ASK_PERMISSIONS);        return;    }    insertDummyContact();}

Page 15: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 15/29

No matter Allow or Deny is chosen, Activity'sonRequestPermissionsResult will always be called to inform a resultwhich we can check from the 3rd parameter, grantResults , like this:

1234567891011121314151617

@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions,     switch (requestCode) {        case REQUEST_CODE_ASK_PERMISSIONS:            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {                // Permission Granted                insertDummyContact();            } else {                // Permission Denied                Toast.makeText(MainActivity.this, "WRITE_CONTACTS Denied"                        .show();            }            break;        default:            super.onRequestPermissionsResult(requestCode, permissions, grantResults);    }}

Page 16: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 16/29

This is how Runtime Permission works. Code is quite complicatedbut be used to it ... To make you application works perfectly withRuntime Permission, you have to handle all the case with the samemethod shown above.

If you want to punch some wall, it is a good time now ...

Handle "Never Ask Again"If user denied a permission. In the second launch, user will get a"Never ask again" option to prevent application from asking thispermission in the future.

Page 17: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 17/29

If this option is checked before denying. Next time we callrequestPermissions , this dialog will not be appeared for this kind ofpermission anymore. Instead, it just does nothing.

However it is quite bad in term of UX if user does something butthere is nothing interact back. This case has to be handled as well.Before calling requestPermissions , we need to check that should weshow a rationale about why application needs the being-requestedpermission throughActivity's  shouldShowRequestPermissionRationale  method. Sourcecode will now look like this:

12345678910111213141516171819202122232425262728293031

final private int REQUEST_CODE_ASK_PERMISSIONS = 123; private void insertDummyContactWrapper() {    int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS);    if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {            if (!shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) {                showMessageOKCancel("You need to allow access to Contacts"                        new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialog,                                 requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},                                        REQUEST_CODE_ASK_PERMISSIONS);                            }                        });                return;            }        requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},                REQUEST_CODE_ASK_PERMISSIONS);        return;    }    insertDummyContact();} private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {    new AlertDialog.Builder(MainActivity.this)            .setMessage(message)            .setPositiveButton("OK", okListener)            .setNegativeButton("Cancel", null)            .create()            .show();}

Page 18: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 18/29

The result are rational dialog will be shown when this permission isrequested for the first time and also be shown if user has evermarked that permission as Never ask again. For the latter case,onRequestPermissionsResult will be called with PERMISSION_DENIEDwithout any permission grant dialog.

Done !

Asking for multiple permissions ata time

Page 19: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 19/29

There is definitely some feature that requires more than onepermission. You could request for multiple permissions at a timewith same method as above. Anyway don't forget to check the 'Neverask again' case for every single permission as well.

Here is the revised code.

1234567891011121314151617181920212223242526272829303132333435363738394041424344

45

final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124; private void insertDummyContactWrapper() {    List<String> permissionsNeeded = new ArrayList<String>();     final List<String> permissionsList = new ArrayList<String>();    if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))        permissionsNeeded.add("GPS");    if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS))        permissionsNeeded.add("Read Contacts");    if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS))        permissionsNeeded.add("Write Contacts");     if (permissionsList.size() > 0) {        if (permissionsNeeded.size() > 0) {            // Need Rationale            String message = "You need to grant access to " + permissionsNeeded.get(            for (int i = 1; i < permissionsNeeded.size(); i++)                message = message + ", " + permissionsNeeded.get(i);            showMessageOKCancel(message,                    new DialogInterface.OnClickListener() {                        @Override                        public void onClick(DialogInterface dialog,                             requestPermissions(permissionsList.toArray(                                    REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);                        }                    });            return;        }        requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),                REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);        return;    }     insertDummyContact();} private boolean addPermission(List<String> permissionsList, String permission) {    if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {        permissionsList.add(permission);        // Check for Rationale Option        if (!shouldShowRequestPermissionRationale(permission))            return false;    }

    return true;

Page 20: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 20/29

When every single permission got its grant result, the result will besent to the same callback method,  onRequestPermissionsResult . Iuse HashMap to make source code looks cleaner and morereadable.

The condition is flexible. You have to set it by your own. In somecase, if even one permission is not granted, that feature will be justsimply disabled. But in some case, it will still work but with limitedfeature. There is no suggestion from me. It is all by your design.

Use Support Library to make code

4546

    return true;}

123456789101112131415161718192021222324252627282930

@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions,     switch (requestCode) {        case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS:            {            Map<String, Integer> perms = new HashMap<String, Integer>();            // Initial            perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);            perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED);            perms.put(Manifest.permission.WRITE_CONTACTS, PackageManager.PERMISSION_GRANTED);            // Fill with results            for (int i = 0; i < permissions.length; i++)                perms.put(permissions[i], grantResults[i]);            // Check for ACCESS_FINE_LOCATION            if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED                    && perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED                    && perms.get(Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {                // All Permissions Granted                insertDummyContact();            } else {                // Permission Denied                Toast.makeText(MainActivity.this, "Some Permission is Denied"                        .show();            }            }            break;        default:            super.onRequestPermissionsResult(requestCode, permissions, grantResults);    }}

Page 21: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 21/29

Use Support Library to make codeforward-compatibleAlthough the code above works perfectly on Android 6.0Marshmallow. Unfortunate that it will crash on Android pre-Marshmallow since those functions called are added in API Level 23.

The straight way is you can check Build Version with code below.

But code will be even more complicated. So I suggest you to usesome help from Support Library v4 which is already prepared forthis thing. Replace those functions with these:

- ContextCompat.checkSelfPermission()

No matter application is run on M or not. This function willcorrectly return PERMISSION_GRANTED if the permission is granted.Otherwise  PERMISSION_DENIED will be returned.

- ActivityCompat.requestPermissions()

If this function is called on pre-M,OnRequestPermissionsResultCallback will be suddenly called withcorrect  PERMISSION_GRANTED  or  PERMISSION_DENIED  result.

- ActivityCompat.shouldShowRequestPermissionRationale() 

12345

if (Build.VERSION.SDK_INT >= 23) {    // Marshmallow+} else {    // Pre‐Marshmallow}

Page 22: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 22/29

If this function is called on pre-M, it will always return false .

ALWAYS replace Activity's  checkSelfPermission ,requestPermissions

and  shouldShowRequestPermissionRationale  with these functionsfrom Support Library v4. And your application will work perfectlyfind on any Android version with same code logic. Please note thatthese functions require some additional parameter: Context orActivity. Nothing special to do, just pass what it wants correctly. Hereis what source code will look like.

Besides we are also able to call the last two methods in Fragmentwith some help from Support Library v13 by callingFragmentCompat.requestPermissions()  and  FragmentCompat.shouldShowRequestPermissionRationale()functions will do exactly the same as Activity's.

Shorten source code with 3rd Party

123456789101112131415161718192021222324

private void insertDummyContactWrapper() {    int hasWriteContactsPermission = ContextCompat.checkSelfPermission(MainActivity.            Manifest.permission.WRITE_CONTACTS);    if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {        if (!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.                Manifest.permission.WRITE_CONTACTS)) {            showMessageOKCancel("You need to allow access to Contacts"                    new DialogInterface.OnClickListener() {                        @Override                        public void onClick(DialogInterface dialog,                             ActivityCompat.requestPermissions(MainActivity.                                    new String[] {Manifest.permission.WRITE_CONTACTS},                                    REQUEST_CODE_ASK_PERMISSIONS);                        }                    });            return;        }        ActivityCompat.requestPermissions(MainActivity.this,                new String[] {Manifest.permission.WRITE_CONTACTS},                REQUEST_CODE_ASK_PERMISSIONS);        return;    }    insertDummyContact();}

Page 23: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 23/29

Shorten source code with 3rd PartyLibraryYou will notice that code is quite complicated. No surprise, there arequite many of 3rd party libraries out there trying to solve this bigthing. I gave a try with quite a lot of them and finally found one thatsatisfy me. It is hotchemi's PermissionsDispatcher(http://hotchemi.github.io/PermissionsDispatcher/).

What is does it exactly the same as I described above but just withshorter and cleaner code. Surely with some trade-off with flexibility.Please give it a try and see if it could be applied in your application. Ifit couldn't, you can go on the direct way which is also my choice rightnow.

What will happen if permission isrevoked while application isopened?As mentioned above, a permission can be revoked anytime throughphone's Settings.

Page 24: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 24/29

So what will happen if permission is revoked when application isopened? I have already given it a try and found that application'sprocess is suddenly terminated. Everything inside application justsimply stopped (since it is already terminated ...). It sounds makesense to me anyway since if OS allows the application to go on itsprocess, it may summon Freddy to my nightmare. I mean evenworse nightmare than currently is ...

Conclusion and SuggestionI believe that you see the big picture of this new permission systemquite clear right now. And I believe that you also see how big issue itis.

Page 25: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 25/29

However you have no choice. Runtime Permission is already used inAndroid Marshmallow. We are at the point of no return. Only thingwe could do right now is to make our application fully support thisnew permission system.

Good news is there are only few permission that requires RuntimePermission flow. Most of the frequently-used permissions, forexample, INTERNET, are in Normal Permission(https://developer.android.com/preview/features/runtime-permissions.html#normal) are automatically granted and you haveno need to do anything with them. In conclusion, there are just fewpart of code that you need to modify.

There are two suggestions to you all:

1) Make Runtime Permission support an urgent issue

2) Don't set application's targetSdkVersion to 23 if your code isnot yet supported Runtime Permission. Especially when youcreate a new project from Android Studio, don't forget to take alook at build.gradle everytime for targetSdkVersion !

Talk about source code modification, I must admit that it is quite abig thing. If code structure is not designed good enough, you mayneed some serious reconstruction which will surely take some time.Or at least I believe that source code need to be refactored for everysingle application. Anyway like I said above, we have no choice ...

In the man time, since permission concept is turned upside down.Right now if some permission is not granted, your application needto still be able to work with limited feature. So I suggest you to list all

Page 26: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 26/29

the feature that related to permission you requested. And writedown all the case possible, if permission A is granted but permissionB is denied, what will happen. Blah blah blah.

Good luck with your code refactoring. Mark it as urgent in your to-dolist and start do it today so it will contains no problem on the dayAndroid M is publicly launched.

Hope you find this article helpful and Happy Coding !

More details are available here(https://developer.android.com/preview/features/runtime-permissions.html).

Author: nuuneoi (Android GDE, CTO & CEO at The Cheese Factory) A full-stack developer with more than 6 years experience on Android ApplicationDevelopment and more than 12 years in Mobile Application Developmentindustry. Also has skill in Infrastucture, Service Side, Design, UI&UX, Hardware,Optimization, Cooking, Photographing, Blogging, Training, Public Speaking anddo love to share things to people in the world!

Tweet 209 298 people like this.Like Share

37 Comments Sort by 

Nitin Sethi · Bangalore, IndiaNice article. Thanks. You need to proof read the article better as you alwaysend up with a number of typos.

Like · Reply ·  3 · Aug 25, 2015 10:05pm · Edited

Rodrigo Graça · Developer at EVOKE ITThis is insane... Are they crazy? Android M should prompt the user, not the app developer....

Oldest

Add a comment...

Page 27: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 27/29

Android M should prompt the user, not the app developer....A way to make sure an app works, will be to ask for all the permissions whenthe app starts, since the process is closed if the users changes it while theapplication is open...

Like · Reply ·  2 · Aug 26, 2015 4:33am

Douglas Drumond · Android Development Analyst at MovileThen you risk the user denying all of them, since they don't trust theapp yet and have no idea why it needs that permission (unless it'sobvious, like a camera app asking for camera permission).Like · Reply · Aug 27, 2015 11:45pm

Rodrigo Graça · Developer at EVOKE IT@Douglas Drumond Ok.... So, it should be the OS (Android) asking forthe permission when the code called something for the first time.....This way, if a camera app suddenly wanted to send one SMS, the userwould notice the prompt for the permission and probably uninstall theapp...

Like · Reply ·  1 · Aug 28, 2015 1:47am · Edited

Virat SinghThank you for this blog post! It helped me get started with the Android Mpermissions. 

I would like to mention that shouldShowRequestPermissionRationale(...) returnsfalse for 2 reasons now with the final Android M SDK update:1. When "Don't ask again" is checked (as you mentioned)2. If the device policy prohibits the app from having that permission (returnsfalse on initial permission prompt)

I think the 2nd reason may cause some issues with your currentimplementation. Since as of the final Android M SDK update (update 3, August2015), shouldShowRequestPermissionRationale(...) always returns false initiallyas well as when "Don't ask again" is checked.

Here is a link to the docs with the explanation:... See More

Like · Reply ·  2 · Aug 26, 2015 11:07am · Edited

David LaumaillierI hope all this is for rooted phones only otherwise I'm in trouble. Didn'tunderstand most of it.Like · Reply · Aug 26, 2015 7:29pm

Douglas Drumond · Android Development Analyst at MovileIf you're not a developer, don't worry. If you're a developer and don'tget it, sorry to inform you, you need to study a little bit, this is not rocketscience.

Like · Reply ·  1 · Aug 27, 2015 11:44pm

David LaumaillierWow, thanks for that insult. Sorry for troubling your superiority with mycomment.

Page 28: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 28/29

Related 

Retrofit 2.0: The biggest update yet on the bestHTTP Client Library for Android(/blog/retrofit-2.0/en)Posted on 6 Sep 2015 12:33

How to setup ACRA, an Android Application CrashTracking system, on your own hostApplication Crash Reports on Android

(/blog/how-to-install-and-use-acra-android/en)Posted on 1 Mar 2015 23:35

comment.Like · Reply · Aug 28, 2015 2:05am

Jiaxin Ji · Works at 慕课网

David Laumaillier 谢谢你温柔的打扰 ! 抱歉拉低你的上限咯~Like · Reply · Aug 31, 2015 1:12am

Show 1 more reply in this thread

Page 29: Everything Every Android Developer Must Know About New Android's Runtime Permission __ the Cheese Factory

1/11/2016 Everything every Android Developer must know about new Android's Runtime Permission :: The Cheese Factory

http://inthecheesefactory.com/blog/things­you­need­to­know­about­android­m­permission­developer­edition/en 29/29

(http://twitter.com/thecheesefact)

(http://facebook.com/inthecheesefactory)

(/blog/en/rss.xml)

Copyright © The Cheese Factory Co.,Ltd. 2015