With the continuous upgrade of Android system, The Android system has also been improved in terms of system security. For example, before Android5.0, users must unconditionally accept the permissions declared in the androidmanifest.xml file for any application installed, otherwise they will have to not install the application. This also allows for some malicious applications, and users’ privacy is not guaranteed. Starting with Android5.0, a check box appears when a user installs an app, allowing the user to select some permissions granted to the app. If you don’t, the app won’t have those permissions. After entering Android6.0, Google further controls permissions. For some dangerous permissions, the application will have the permissions only after the user authorizes them, which further strengthens the security of the application. But this change also makes us can run normally before the application has been affected to a certain extent, we must do certain adaptation to ensure the normal operation of our application, let’s learn about the permissions management mechanism of Android6.0.

Normal permissions and dangerous permissions

The Android website explains normal and dangerous permissions:

  • Normal permissions cover areas where an application needs access to data or resources outside its sandbox, but there is little risk to user privacy or other application operations. For example, the permission to set the time zone is a normal permission. If an application declares that it needs normal permission, the system automatically grants the permission to the application.
  • Dangerous permissions cover areas where the application requires data or resources that involve users’ private information, or where the data stored by the user or the operations of other applications may be affected. For example, being able to read a user’s contacts is a dangerous privilege. If an application claims that it requires hazardous permission, the user must explicitly grant the permission to the application.

In addition to the normal and dangerous permissions mentioned above, there is another concept that needs to be understood. The simple understanding of permission groups is that permissions are grouped, such as READ_CALENDAR permissions and WRITE_CALENDAR permissions belong to the CALENDAR group. Any permission can belong to a permission group, including normal permissions and application-defined permissions. However, user experience is affected only when permissions are in danger. You can ignore the normal permission group, so you can say that all dangerous Android system permissions belong to the permission group.

The hazard permissions and their groups are listed below:

Permissions set permissions
CALENDAR READ_CALENDAR

WRITE_CALENDAR
CAMERA CAMERA
CONTACTS READ_CONTACTS

WRITE_CONTACTS

GET_ACCOUNTS
LOCATION ACCESS_FINE_LOCATION

ACCESS_COARSE_LOCATION
MICROPHONE RECORD_AUDIO
PHONE READ_PHONE_STATE

CALL_PHONE

READ_CALL_LOG

WRITE_CALL_LOG

ADD_VOICEMAIL

USE_SIP

PROCESS_OUTGOING_CALLS
SENSORS BODY_SENSORS
SMS SEND_SMS

RECEIVE_SMS

READ_SMS

RECEIVE_WAP_PUSH

RECEIVE_MMS
STORAGE READ_EXTERNAL_STORAGE

WRITE_EXTERNAL_STORAGE

In addition to the above table, we can also view the danger permissions and their groups on the command line. To get the result, type the following on the command line:

adb shell pm list permissions -g -d
Copy the code

Second, the application request dangerous permission processing

If the device is running Android 6.0 (API level 23) and the application’s targetSdkVersion is 23 or higher, the system will do the following when the user requests dangerous permissions:

  • If an application requests one of the dangerous permissions listed in its listing, and the application does not currently have any permissions in the permissions group, the user is presented with a dialog box describing the permissions group the application wants to access. The dialog box does not describe specific permissions within the group. For example, if an application requests READ_CONTACTS permission, the system dialog simply states that the application needs access to the device’s contact information. If the user approves, the application is granted permission to request it.
  • If an application requests one of the dangerous permissions listed in its manifest, and the application already has another dangerous permission in the same permission group, the system grants it immediately without any interaction with the user. For example, if an application has requested and is granted READ_CONTACTS permission, and then requests WRITE_CONTACTS, the system will grant that permission immediately.

An important point is that the system only tells users which groups of permissions the application requires, but not the specific permissions

Three, code actual combat authority management mechanism

The above said so many theories, now start the real combat, in fact, the following steps can be completed simply, we take the application for call permission as an example:

1. Add the required permissions to the androidmanifest.xml file (for systems below Android6.0)

Add the following permissions to the androidmanifest.xml file

<uses-permission android:name="android.permission.CALL_PHONE"/>
Copy the code

2. Check the danger permission

Must first before we start calling to check whether we have permission for the phone, for the normal permissions, the system default is granted, but to make a phone call to the dangerous permissions we will have to check first, here called ContextCompat. CheckSelfPermission () method to inspect, If the result of the check is that the user has granted us this permission, then we can directly invoke the call logic, if not, then we must apply for permission.

if(ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) ! = PackageManager. PERMISSION_GRANTED) {/ / do permissions apply for processing ActivityCompat. RequestPermissions (this, new String[]{Manifest.permission.CALL_PHONE}, CALL_PHONE_REQUEST_CODE); }else{// The user is authorized to directly process the business logic of the calldoCallPhone();
}
Copy the code

3. Apply for authorization

. As you can see we use ActivityCompat requestPermissions application permissions () method, the method of the second parameter can pass in an array of permissions, we can apply for more than a one-time permission, the third argument is a request code, used to according to the result of application in the next step we do correction processing.

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, CALL_PHONE_REQUEST_CODE);
Copy the code

4. Process the callback request

We rewrite the onRequestPermissionsResult () method to handle the correction results

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode){
        caseCALL_PHONE_REQUEST_CODE: // Call permission callback processif(grantResults [0] = = PackageManager. PERMISSION_GRANTED) {/ / phone permission has been granteddoCallPhone();
            }else{/ / the refused permission to request, prompt the user permissions are not granted Toast. The makeText (this,"Permission request failed", Toast.LENGTH_SHORT).show();
            }
            break;
        default:
            break; }}Copy the code

The above requestCode is the requestCode we provided when applying for the right limit, and grantResults stores the application results corresponding to each of our permissions. Since we only applied for one permission,grantResults [0] is ok.

Of course, if you ask a user for permission and the user rejects your permission, the next time the user asks for permission, the user will still pop up the authorization window, and you may want to explain to the user why you are using the permission more clearly. This time you need to use ActivityCompat. ShouldShowRequestPermissionRationale () this method.

This method will return false when the application is first installed and true when the user denies your permission once

Note: When the user clicks on the authorization windowNo longer askCheck box, the method returnsfalse, you can make some reactions based on the user’s behavior, but the general permission application window has a certain description of the application permission, unless special circumstances, we do not need to explain the permission.

Four, more elegant implementation of permission application and management

Having said all that, you can see that there are only a few important steps to applying for permissions, but we can’t always write code every time we need to apply. At this point, we can look at other libraries and actually do it ourselves. PermissionGen and MPermissions are recommended

  • PermissionGenIs a Korean encapsulation, project link here: https://github.com/lovedise/PermissionGen
  • MPermissionsIs hong god encapsulated library, project link here: https://github.com/hongyangAndroid/MPermissions

The first library is based on runtime annotations that affect performance when used, and the second library is based on compile-time annotations that have no impact on performance.