This article is a systematic review of Android permissions related knowledge, in daily development, we have used permissions, but some details of permissions we may master is not comprehensive enough, this article will be comprehensive for you to introduce permissions related knowledge. Of course, this article is still a reference to Google’s official document: Application Permissions.
This article directory
First, understand Android permissions
(1) Why does the Android system need permission?
The purpose of setting permissions on Android is to protect the privacy of Android users. Android applications must ask users for permission to access sensitive data (such as contacts and text messages), as well as access to certain system functions (such as cameras and microphones). Depending on the function, the system may automatically grant permissions or prompt the user to approve the request. One of the core design points of Android’s security architecture is that, by default, no application can perform any operation that could adversely affect other applications, the operating system, or the user. This includes reading or writing to a user’s private data (such as contacts or E-mail), reading or writing to another application’s files, performing network access, and so on.
(2) Classification of authority
Permissions are classified into several protection levels. Protection levels affect whether runtime permission requests are required:
- Normal permissions Indicates the Normal permission
- Signature Permissions Specifies the Signature permission
- Dangerous Permissions Dangerous permission
What we need to know is normal and dangerous permissions.
1. Normal permission
Normal permissions cover areas where an application needs to access data or resources outside the sandbox, but these areas pose little risk to user privacy or other application operations. For example, the permission to set the time zone is a normal permission.
If the application declares in its manifest that it requires a normal permission, the system automatically grants it at installation time. The system does not prompt the user to grant normal rights, and the user cannot revoke those rights.
- ACCESS_LOCATION_EXTRA_COMMANDS
- ACCESS_NETWORK_STATE
- ACCESS_NOTIFICATION_POLICY
- ACCESS_WIFI_STATE
- BLUETOOTH
- BLUETOOTH_ADMIN
- BROADCAST_STICKY
- CHANGE_NETWORK_STATE
- CHANGE_WIFI_MULTICAST_STATE
- CHANGE_WIFI_STATE
- DISABLE_KEYGUARD
- EXPAND_STATUS_BAR
- GET_PACKAGE_SIZE
- INSTALL_SHORTCUT
- INTERNET
- KILL_BACKGROUND_PROCESSES
- MODIFY_AUDIO_SETTINGS
- NFC
- READ_SYNC_SETTINGS
- READ_SYNC_STATS
- RECEIVE_BOOT_COMPLETED
- REORDER_TASKS
- REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
- REQUEST_INSTALL_PACKAGES
- SET_ALARM
- SET_TIME_ZONE
- SET_WALLPAPER
- SET_WALLPAPER_HINTS
- TRANSMIT_IR
- UNINSTALL_SHORTCUT
- USE_FINGERPRINT
- VIBRATE
- WAKE_LOCK
- WRITE_SYNC_SETTINGS
2. Dangerous permissions
Hazardous permissions include areas where an application needs data or resources that involve a user’s private information, as well as areas where the user’s stored data or operations of other applications could be affected. For example, reading a user’s contacts is a dangerous privilege. If an application declares that it requires a dangerous permission, the user must explicitly grant the permission to the application. Until the user approves the permission, the application cannot provide functionality that depends on the permission.
To use dangerous permissions, the application must prompt the user to grant permissions at runtime.
(3) How to declare a permission?
An application must publish the required permissions by using the
tag in the manifest file (Androidmanifest.xml). For example, to declare network access:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">// Declare network access permission<uses-permission android:name="android.permission.INTERNET"/>
<application .>.</application>
</manifest>
Copy the code
If the normal permissions listed in the manifest file of the application (that is, permissions that do not pose too much risk to user privacy or device operations) are automatically granted to the application.
If the permissions listed in the application list are hazardous (that is, permissions that may affect user privacy or normal operation of the device), the permissions must be granted with the user’s consent.
(4) Handling methods of dangerous permissions in different Versions of Android
The way That Android requests danger permission from the user depends on the Version of Android running on the user’s device and the targetSdkVersion we set in the app. There are two main ways to handle it:
- Runtime request: Android 6.0 and higher
- Install request: Android 5.1.1 and later
- Runtime request:
If the phone Android version is 6.0 (API level 23) or higher and the app targetSdkVersion is 23 or higher, the user will not receive any application permission notification at installation. The application must ask the user to grant dangerous permissions at run time. When an application requests a permission limit, the user is presented with a system dialog that tells the user which permission group the application is trying to access. The dialog box contains a deny and allow button.
If the user rejects the permission request, the next time the application requests the permission, the dialog box will contain a check box that will not prompt the user for a permission request.
The following is an example of applying for the photo permission:
As you can see, the first time you choose to reject the box, the second time the box appears a “do not ask” check box, checked, rejected again, then the permission application dialog box will not pop up.
If the user selects “Allow”, it does not mean that the application will always have the permission. The user can also go to the system Settings page and turn off the granted permissions, so we have to check and apply for the permissions at run time to prevent the SecurityException error that causes the application to crash at run time.
- Installation request:
If the phone’s Android version is 5.1.1 (API level 22) or lower, and the application’s targetSdkVersion is 22 or lower, the system will automatically require the user to grant all dangerous permissions to the application at install time.
If the user clicksAccept
, all permissions requested by the application will be granted. If the user rejects the permission request, the system will cancel the installation of the application. If an application update requires additional permissions, the user will be prompted to accept these new permissions before updating the application.
(5) Two special permissions
There are two permissions that do not behave like normal and dangerous permissions: SYSTEM_ALERT_WINDOW and WRITE_SETTINGS
These are two particularly sensitive permissions, so most applications should not use them. If the application requires one of these permissions, it must declare it in the listing and send an intent request to the user for authorization. The system responds to this intent by presenting the user with a detailed administrative screen.
Take applying for SYSTEM_ALERT_WINDOW as an example:
Step 1: First declare permissions in the manifest file:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Copy the code
Step 2: Apply for permission (version 6.0 or later)
// Before 6.0, the floating window permission is enabled by default, you can use directly.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(! Settings.canDrawOverlays(context)) { Intent intent =new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(intent);
return; }}Copy the code
(6) Permission group
The Android system groups all dangerous permissions into groups called permission groups.
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 |
If the mobile Android version is 6.0 (API level 23) or higher, and the application targetSdkVersion is 23 or higher, then when the application requests the danger permission, the system will do the following:
If the application does not currently have any permissions in the permission group, the system displays a permission request dialog box to a user who describes the permission group that the application wants to access. The dialog box does not describe specific permissions in the group. For example, if an application requests the READ_CONTACTS permission, the system dialog tells the application only the contacts that need to access the device. If the user gives approval, the system will only give the application the permissions it requested.
If the application has been granted another dangerous permission in the same permission group, the system immediately grants that permission without any interaction with the user. For example, if an application previously requested and was granted the READ_CONTACTS permission, and then it requested WRITE_CONTACTS, the system immediately granted the permission without displaying the permissions dialog to the user.
The above is the official version, which is simply this: dangerous permissions that belong to the same group are automatically combined and granted. If a user grants an application to a certain group of permissions, the application will get all permissions under that group (provided the relevant permissions are declared in androidManifest.xml).
But is this really the case? Let’s try something that belongs to the same permission groupREAD_CONTACTS
Permissions andWRITE_CONTACTS
Permissions. Officially, if I authorize it firstREAD_CONTACTS
Permissions, soWRITE_CONTACTS
Permissions are granted automatically. Let’s see how this works in action:And you can see when we first grantedREAD_CONTACTS
After the permission, go to apply againWRITE_CONTACTS
Permission, the dialog box is still displayed for the user to authorize, which is obviously inconsistent with the official documentation. But at the same time the authorities advised us,Do not base your application logic on the structure of these privilege groups, because in future releases, a particular privilege may be moved from one group to anotherTherefore, our code logic should not rely on the permission group, but should explicitly request every permission it needs, even if the user has already granted another permission in the same group.
How to request permission
Every Android app runs in a sandbox with limited access. If an application needs to use resources or information outside its own sandbox, it must request permissions. To declare that an application requires certain permissions, list them in the application list and then ask the user to approve each permission at run time (for Android 6.0 and later).
(1) Add permission to the manifest file
Whatever permissions the application requires, they need to be declared in the manifest file. The system takes different actions based on the sensitivity of the declared permission. Some permissions are considered “normal” and are granted immediately upon application installation. Others are considered “dangerous” and require explicit access.
(2) check the authority
If your application requires a dangerous permission, you must check that you have that permission every time you perform an operation that requires that permission. Starting with Android 6.0 (API level 23), users can revoke permissions from any app at any time, even if the app is targeted at a lower API level. Therefore, even if the application used the camera yesterday, it cannot be assumed that it still has that permission today.
To check whether the application has a permissions, please call ContextCompat. CheckSelfPermission () method. For example, the following code snippet shows how to check if an Activity has permission to write data to a calendar:
if(ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR) ! = PackageManager.PERMISSION_GRANTED) {// Permission is not granted
}
Copy the code
If the application has this permission, the method returns PERMISSION_GRANTED and the application can continue. If the application does not have this permission, the method returns PERMISSION_DENIED, and the application must explicitly ask the user to grant the permission.
(3) Request permission
When the application receives PERMISSION_DENIED from checkSelfPermission(), it needs to prompt the user to grant the permission. Android provides several ways to requestPermissions(such as requestPermissions()), as shown in the code snipple below. When these methods are called, a standard Android dialog box is displayed that cannot be customized.
// Here, thisActivity is the current activity
if(ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.READ_CONTACTS) ! = PackageManager.PERMISSION_GRANTED) {// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed; request the permission
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.}}else {
// Permission has already been granted
}
Copy the code
In some cases, you need to help users understand why an application needs a certain permission. For example, if a user launches a photography app, the user might not be surprised that the app requests permission to use the camera, but the user might not understand why the app wants access to the user’s location or contacts. An explanation can be provided to the user before the request permission is applied. A good practice is to provide an explanation if the user has previously rejected the permission request. We by calling shouldShowRequestPermissionRationale () method to implement. This method returns true if the user previously rejected the request. This method returns false if the user has previously denied the permission and checked the do not Ask option in the permission request dialog box, or if the device policy forgives the permission. (Note that if the user has denied the permission and checked do not ask, Even if the requestPermissions method is called in the logic that returns false, the selection box will no longer pop up.
(4) Processing permission request response
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request.}}Copy the code
3. Customize permissions
(1) Background
Android is a privilege separated operating system in which each application runs with a unique system ID (Linux user ID and group ID). The system is also called the different parts, and each part has its own logo. As a result, Linux isolates applications from each other and from the system. Applications can customize permissions to provide other applications with access to their own functionality.
(2) How to customize permissions
To customize permissions, you can declare them using the
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp" >
<permission
android:name="com.example.myapp.permission.DEADLY_ACTIVITY"
android:label="@string/permlab_deadlyActivity"
android:description="@string/permdesc_deadlyActivity"
android:permissionGroup="android.permission-group.COST_MONEY"
android:protectionLevel="dangerous" />.</manifest>
Copy the code
Attribute explanation:
- Name: indicates the name of the user-defined permission. Fill in this name if another app references this permission.
- Lable: a label that describes the key functions protected by this permission (keep it short). The value displayed to the user is a string.
- Description: Description, longer than label, of the permission. The value is obtained from the resource file and cannot be directly written to a string value.
- PermissionGroup: permissionGroup. This attribute is optional. In most cases, the group should set it to a standard system (android. The Manifest. Permission_group), although a group can define your own.
- ProtectionLevel: protectionLevel. It is a required attribute.
Let’s write a concrete example: we define an Activity in process 1, set access permissions for that Activity, and let process 2 access it.
Process 1:
Androidmanifest.xml file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.chenyouyu.permissiondemo">// The user-defined permission level is normal<permission
android:name="com.example.myapp.permission.SECOND_ACTIVITY"
android:label="abc"
android:description="@string/permdesc_SecondActivity"
android:permissionGroup="android.permission-group.COST_MONEY"
android:protectionLevel="normal" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">/ / for SecondActivity plus android: permission = "com. Example. Myapp. Permission. SECOND_ACTIVITY"<activity
android:name=".SecondActivity"
android:exported="true"
android:permission="com.example.myapp.permission.SECOND_ACTIVITY">
<intent-filter>
<action android:name="com.cyy.jump" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>.</manifest>
Copy the code
Process 2:
Androidmanifest.xml file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.chenyouyu.permissiondemo2">// Declare permissions in the AndroidManifest<uses-permission android:name="com.example.myapp.permission.SECOND_ACTIVITY"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Copy the code
MainActivity.java
Intent intent = new Intent();
intent.setAction("com.cyy.jump");
intent.addCategory(Intent.CATEGORY_DEFAULT);
if(intent.resolveActivity(getPackageManager()) ! =null) {
startActivity(intent);
}
Copy the code
Run process 1 first, then process 2.
(3) Pay attention to user-defined permissions
1. The two applications have the same permissions
Android does not allow two different apps to define the same name permissions (unless the two apps have the same signature), so be careful when naming them. Software with the same custom permissions must use the same signature, otherwise the latter program cannot be installed.
2. Relationship with the application installation sequence.
Scenario: App A has permission PermissionA, and App B has permission PermissionA.
Scenario 1: The protection level of PermissionA is Normal or Dangerous. App B is installed first and App A is installed later. In this case, App B cannot obtain the permission of PermissionA. App A is installed first and App B is installed later. Open App A from App B and everything works.
Scenario 2: The protection level of PermissionA is signature or signatureOrSystem. App B is installed first, and App A is installed later. If App A and App B have the same signature, App B can obtain PermissionA permissions. If the signatures of App A and App B are different, App B cannot obtain the PermissionA permission. That is, for apps with the same signature, as long as the permission is declared, the app requesting the permission will get the permission no matter the installation sequence.
This also indicates that for system apps with the same signature, the installation process does not consider permission dependencies. When installing system apps, you can install them in a certain order (such as sorting by name, sorting by directory location, etc.). After all apps are installed, all the apps with permission will get permission.
3. Obtain permissions and be compatible with versions
Android6.0 introduces dynamic permissions, as everyone knows. The previously mentioned custom permission security level android:protectionLevel will affect the use of permissions on Android6.0+
Android :protectionLevel=”normal” : dynamic application is not required. Android :protectionLevel=” Dangerous “: dynamic application is required
Reference article:
- Blog.csdn.net/bingducaiju…
- www.jianshu.com/p/b60cde583…