Introduction
Prior to the M release, the Android permissions model has been an all-or-nothing decision for users at install time. This meant that if a user wanted to use an app, they first had to accept every permission included in the application or choose to not install it at all. This led to many developers losing out on app installs, a trust disconnect between users and developers, and other privacy concerns.
Under the new permissions model, users will be able to approve permissions at runtime as they are needed and can deny those permissions at any time. In this article, you will learn how this change in handling permissions will affect you as a developer and how your users will experience your applications.
It should be noted that this article was written before the official release of Android M, so some information may change with the official release.
1. What Requires Permissions?
While Android M still requires permissions to be declared in AndroidManifest.xml, users will now be required to approve or deny the use of that permission at runtime. One important change in the new version of Android is that android.permission.INTERNET
and android.permission.WRITE_EXTERNAL_STORAGE
have been downgraded from a rating of dangerous to normal. This means that you do not need to prompt the user before use.
When requesting permission approval, the user will be prompted based on the permission's group, rather than being asked to approve every single permission within a group. This means that if your application needs to both send and receive SMS messages, your user will only be prompted to approve the SMS permission group. Below is a list of the currently supported permission groups in Android M Developer Preview 2 as seen from system settings.
It should also be noted that Android features a robust Intent
system, which allows developers to request data from other applications. Rather than needing to request the camera permission and develop an application that uses the Camera APIs from scratch, you can request that the user take a picture using an already trusted camera application in order to get an image into your app. The permissions involving the camera will be handled by the camera app.
2. How to Ask for Permission?
When you need to use a feature that requires a permission, there's a general flow of events that will happen. You first need to see if that permission has already been approved by your user.
If the user has not approved the permission, you can present them with a permission request dialog. The first time you present this to the user, they will have to either deny or approve the permission.
However, if they have previously denied the permission and are asked again, they will have the option to opt out of ever being asked for that permission again.
You can check if a permission has been previously granted by calling checkSelfPermission
before using a feature that will require that permission. This method returns an int
value based on wether that permission is granted or not.
If it is equal to PackageManager.PERMISSION_GRANTED
, then you can continue as expected. However, if that permission has not been previously granted, you can request it with requestPermissions
, passing in an array of permission strings and a custom int
request code for keeping track of your app's logic flow.
int hasLocationPermission = checkSelfPermission( Manifest.permission.ACCESS_FINE_LOCATION ); int hasSMSPermission = checkSelfPermission( Manifest.permission.SEND_SMS ); List<String> permissions = new ArrayList<String>(); if( hasLocationPermission != PackageManager.PERMISSION_GRANTED ) { permissions.add( Manifest.permission.ACCESS_FINE_LOCATION ); } if( hasSMSPermission != PackageManager.PERMISSION_GRANTED ) { permissions.add( Manifest.permission.SEND_SMS ); } if( !permissions.isEmpty() ) { requestPermissions( permissions.toArray( new String[permissions.size()] ), REQUEST_CODE_SOME_FEATURES_PERMISSIONS ); }
Once requestPermissions
is called, the user is presented with a request dialog for each permission group that your application is asking permission for. It is best practice to only request permissions as needed, rather than in bulk when your user first starts your application.
When your user is done with the dialogs, onRequestPermissionsResult
is called and can be accessed in your Activity
. This is where you either start your feature or handle the situation where your user has denied one or more permissions.
An example of how to check if a permission has been granted or denied is shown below. If the user has denied any required permissions for your feature, you should disable that feature and let the user know why it doesn't work in your application.
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch ( requestCode ) { case REQUEST_CODE_SOME_FEATURES_PERMISSIONS: { for( int i = 0; i < permissions.length; i++ ) { if( grantResults[i] == PackageManager.PERMISSION_GRANTED ) { Log.d( "Permissions", "Permission Granted: " + permissions[i] ); } else if( grantResults[i] == PackageManager.PERMISSION_DENIED ) { Log.d( "Permissions", "Permission Denied: " + permissions[i] ); } } } break; default: { super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } }
3. Legacy Apps on Android M
While apps that are built targeting Android M are required to implement the new permissions dialogs and methods, apps built for previous versions of Android will still present users with a list of permissions at install time. Although permissions are accepted before users can use your app, they can still be revoked at any time.
Since the infrastructure for handling revoked permissions will not be available in applications targeting less than Android M, any features that would have required permissions will return null
, 0
, or an empty value when permissions are not granted. This can lead to unexpected behavior in apps, so it is recommended that developers prepare to upgrade their apps to support the new Android M permission model as soon as possible.
Conclusion
In this article, you have learned about the new Android M permission model and how to support updated permissions in your applications. We've also covered how apps will respond to the new version of Android when they have been built for previous versions. Using this information, you should be able to get your applications ready for the official release of the next update to Android.
Comments