Android Marshmallow Permissions
The Android Marshmallow operating system (Android 6.0) brings many new features and functions to the Android playground. From a developer’s perspective at least, the most important of these is the new system permissions model. Permissions are used to grant or revoke an apps access to particular features of the device they are being used on. Although permissions are nothing new to Android, the way in which they are used with the advent of SDK v23 is new. When a user installs an app on Marshmallow, they will have the ability to revoke or grant access to some of the system features the app can use. Although this is great from a users perspective, app developers must be aware that a user may decide to prevent their app from using key features, which could in turn lead to their apps crashing. The system permissions have been broken down into 9 groups. These are:Calendar READ_CALENDAR WRITE_CALENDARPhone READ_PHONE_STATE CALL_PHONE READ_CALL_LOG WRITE_CALL_LOG ADD_VOICEMAIL USE_SIP PROCESS_OUTGOING_CALLSCamera CAMERASMS SEND_SMS RECEIVE_SMS READ_SMS RECEIVE_WAP_PUSH RECEIVE_MMSContacts READ_CONTACTS WRITE_CONTACTS GET_ACCOUNTSSensors BODY_SENSORSLocation ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATIONStorage READ_EXTERNAL_STORAGE WRITE_EXTERNAL_STORAGEMicrophone RECORD_AUDIO If any permission in a group is granted, like READ_PHONE_STATE in the Phone group, then all other permissions in that group, such as CALL_PHONE and ADD_VOICEMAIL to name but a few, will also be granted. Each one of these permissions can be characterized by a protection level. A protection level indicates the risk that is implied by the permission, and the strategy the Android system should employ when deciding if the requesting app should be granted it or not. Normal – This is the default protection level of a permission. It is a low risk permission that can cause the user no real harm as it grants requesting apps access to isolated application level features. Dangerous – A high risk permission which may require a greater level of trust. It grants apps access to private user data or the ability to control the device in a way that could negatively impact the user. e.g Allowing the application to view SMS messages. Signature – A permission which is only granted to applications that are signed with the certificate that is used by the application which declared the permission. SignatureOrSystem – A permission which is like the signature permission, but is only granted to apps that are bundled into the Android system image. This permission is rarely used by developers, it’s only required to be used where multiple application vendors have their apps built into the Android system image and, because of this, need to share specific features amongst each other. What does this mean for developers? Apps targeting SDK v23 will not be granted any permissions when the app is being installed. The app will need to prompt the user to grant or deny access to a permission as it is encountered within the app during runtime. Failing to do this will cause the app to throw a SecurityException, resulting in an app crash. Developers must remember that even if a user has granted access to a particular feature, they may revoke this feature at any time. In the event that this happens the app must be able to handle this gracefully i.e Not crash. Apps should also empty any relevant data when a user explicitly denies permission to a particular feature, where relevant. The usage of the GET_ACCOUNTS permission has also been modified. Apps that previously used the GET_ACCOUNTS permission no longer need to do this for SDK v23, provided they are only using it to access their own account. There is a small trick that can be used for apps that use the GET_ACCOUNTS permission and have a minimum SDK version below v23. <uses-permission android:name="android.permission.GET_ACCOUNTS" android:maxSdkVersion="22" /> This maxSdkVersion attribute allows developers to specify an SDK where the app stops requesting that particular permission. On the other hand developers can also specify that they only want a particular permission to be requested if the user’s device is running Marshmallow or above. <uses-permission-sdk-23 android:name="android.permission.WRITE_CONTACTS"/> Requesting Permissions at Runtime Before a developer can request a permission they must first determine if the permission is already granted or not. Android provides a handy function for this as follows int permissionResult = getActivity().checkSelfPermission(WRITE_EXTERNAL_STORAGE); This will return a PERMISSION_GRANTED or PERMISSION_DENIED any permission that is passed to it. Support annotations could also be used @RequiresPermission(WRITE_EXTERNAL_STORAGE); As I have already mentioned, the user has the ability to deny or allow access to a feature when prompted by the application. If the application prompts the user for a feature for a second time, then the dialog box contains a “Never ask again” checkbox, like below. If the user ticks this box and selects deny again then the developer is left with a couple of options. Some form of fallback could be enabled. The feature could be disabled entirely. The app could display another dialog box, explaining to the user why the app is requesting access to the particular permission. This dialog box could then redirect the user to the app’s settings screen to allow them to manually enable the permission. Developers can check if the user has clicked this “Never ask again” box by calling the shouldShowRequestPermissionRationale inside the onRequestPermissionsResult method. Conclusion Although the new Android permissions model can cause some heartache for developers, overall it is a great step forward for the Android platform, as it allows users to have more control over their applications. Users are more likely to download a broader range of applications as they have the ability to turn off any features that they do not trust.