Effective Handling of Permissions in Android: A Practical Guide
Learn how to effectively deal with the new runtime permissions in Android applications. From distinguishing between dangerous and normal permissions to practical implementation, this post offers a comprehensive guide.
What are Android Runtime Permissions?
Starting from Android 6.0 (SDK 23), users are prompted at runtime to grant certain permissions when needed. An important question arises: Will older apps run on Android Marshmallow? The answer is yes if the targetSdkVersion is set to 22 or lower. However, it’s worth noting that under Marshmallow, users can revoke dangerous permissions from the app’s settings. Calling a function that requires a permission not yet granted by the user results in an exception (java.lang.SecurityException), potentially crashing the application. Hence, integrating this new Android permission model into our application is crucial.
Dangerous and Normal Android Permissions
Android distinguishes between dangerous and normal permissions. Both types must be specified in the application’s manifest. From Android 6.0 onwards, only dangerous permissions are checked at runtime, while normal permissions are ignored. An example of a normal permission is android.permission.INTERNET. Dangerous permissions are grouped into categories to help users understand what they’re allowing the application to access. When a user accepts a permission within a group/category, they accept the entire group. Examples of dangerous permissions include android.permission.FINE_LOCATION and android.permission.COARSE_LOCATION. Granting one of the location permissions grants all.
Requesting Android Runtime Permissions
The method requestPermissions(String[] permissions, int requestCode)
is a public method used to request dangerous permissions. We can request multiple dangerous permissions by passing a string array of permissions. Note: Android permissions belonging to different groups would prompt the user with a separate dialog for each. If they belong to the same group, only one dialog prompt is displayed. The results of the requests are passed to the onRequestPermissionResult
method.
Example:
Suppose we want to access the camera and location in our app. Both are dangerous permissions. We display a dialog requesting access to these permissions when the application starts.
String[] perms = {"android.permission.FINE_LOCATION", "android.permission.CAMERA"};
int permsRequestCode = 200;
requestPermissions(perms, permsRequestCode);
@Override
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){
switch(permsRequestCode){
case 200:
boolean locationAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED;
boolean cameraAccepted = grantResults[1]==PackageManager.PERMISSION_GRANTED;
break;
}
}
To prevent the user from having to accept permissions again, we recheck whether the permissions are present despite previous approval. For this, the checkSelfPermission(String perm)
method must be called on each permission.
Project Structure of Android Runtime Permissions
The main layout (content_main.xml) contains the two buttons for checking and requesting permissions.
With effective permission management, Android developers can ensure their apps function smoothly while respecting user privacy. Proper implementation of runtime permissions according to Google’s guidelines is a crucial step for the success of any modern Android application.