Android 6.0 dynamic permission request 1. Overview
The permissions applied before Android 6.0 (API 23) are all granted at the time of installation, and the runtime app no longer needs to ask the user. Permissions are categorized on Android 6.0 or later, and some permissions that involve user privacy can be dynamically granted at run time based on the user's needs. This does not require you to be forced to consent to certain permissions at installation time.
2. Normal and Dangerous permissions
Android system permissions are divided into several protection levels. The two most important levels of protection you need to know are normal permissions and dangerous permissions:
(1) Normal permission:
Covers areas where your app needs to access its sandbox external data or resources, but is less risky for user privacy or other application operations. These permissions are granted when the app is installed, and the runtime no longer asks the user. For example: Network access, WiFi status, volume settings, and so on. Complete normal permissions list refer to official website normal permissions.
(2) Dangerous rights:
Covers areas where the application requires data or resources that involve user privacy information, or that may affect the operations of the user's stored data or other applications. For example: Reading contacts, reading and writing memory data, obtaining user location, etc. If application claims require these dangerous permissions, you must explicitly tell the user at run time to have the user grant it manually.
3. Permission groups
The Android system groups all dangerous permissions, called permission groups. Dangerous permissions that belong to the same group are automatically merged and granted, and the user grants permission to apply a permission group, and the app obtains all the permissions under that permission group (provided the relevant permissions are declared in Androidmanifest.xml).
The list of dangerous permissions and permission groups is as follows:
PS: The permission groups for the dangerous permissions that are declared in Androidmanifest.xml can be viewed in the permissions, application information, app, settings, and so on, and can be manually authorized and de-authorized.
Permission groups and permissions are represented in the Android code as string constants, defined in the fields of the following two static inner classes:
- Android. Manifest.permission_group (Permission Group):
Manifest.permission_group.CALENDAR
Manifest.permission_group.STORAGE
......
- Android. Manifest.permission (permissions):
Manifest.permission.READ_CALENDAR
Manifest.permission.READ_EXTERNAL_STORAGE
......
4. Request permissions at run time
The device system is Android 6.0 (API 23) or later, and the app's targetsdkversion is 23 or higher, and for dangerous permissions declared in Androidmanifest.xml, you need to dynamically request user authorization at run time.
The API for dynamic permission request-related operations is encapsulated android.support.v4
in the package, and the need to initiate the request permission is Activity
inherited directly or indirectly android.support.v4.app.FragmentActivity
.
PS: You can also android.support.v4.app.Fragment
initiate a permission request in a direct or indirect inheritance Fragment
.
The following methods are mainly included in the code step:
(1) Check permissions
Check Permissions Contextcompat.checkselfpermission (context context, String permission)
return value ( android.content.pm.PackageManager
constant in):
- Have permission:
PackageManager.PERMISSION_GRANTED
- No permissions:
PackageManager.PERMISSION_DENIED
Use this method to determine whether you have the specified permission before executing the permission-related code when the application needs to use dangerous permissions. Has permissions, the code that the design requires permission continues to execute, and no permissions are requested to grant permissions to the user.
(2) Interpretation of permissions
Interpreting permissions Activitycompat.shouldshowrequestpermissionrationale (activity activity, String permission)
Determine if it is necessary to explain to the user why this permission is required. If the application requests this permission for the first time but is rejected by the user, then calling the method will return true, and it is necessary to give the user a detailed explanation of why this permission is required (this method is considered optional by the individual).
PS: If the application is denied the first time this permission is requested by the user, and the second time this permission is requested, the user has checked the Permission Request dialog box "Do not ask again", this method returns FALSE. This method also returns false if the device specification prohibits the app from owning the permission.
(3) Request permission
// 请求权限ActivityCompat.requestPermissions(Activity activity, String[] permissions, int requestCode)
This method is called to request permission from the user when it detects that the app does not have the specified permissions. Call this method to ask the user for permission to allow or deny for the Permission Request dialog box.
Ps:
- A permission parameter is passed in an array, which can be called to request multiple permissions at once;
- The incoming permission array parameter is in a single specific permission, but when the box asks the user for authorization, the permissions that belong to the same permission group are automatically merged to ask for authorization once;
- The requested permission must be declared in the androidmanifest.xml beforehand, otherwise, when calling this method request, it will not bounce the box, but return the result of "reject" directly;
- The first time the permission is requested, the user clicks on "Deny", the second time to request the permission, the dialog box will appear "no longer ask" check box, if the user ticked "no longer ask" and click "Reject", then request this permission group will not bounce box, but directly return "rejected" results.
(4) Processing results
The result of requesting permission returns and receives an activity that returns similar, overridden, FragmentActivity
or (v4) Fragment
in a onRequestPermissionsResult(...)
method.
/** * 处理权限请求结果 * * @param requestCode * 请求权限时传入的请求码,用于区别是哪一次请求的 * * @param permissions * 所请求的所有权限的数组 * * @param grantResults * 权限授予结果,和 permissions 数组参数中的权限一一对应,元素值为两种情况,如下: * 授予: PackageManager.PERMISSION_GRANTED * 拒绝: PackageManager.PERMISSION_DENIED */
@Overridepublic void Onrequestpermissionsresult (int requestcode, String permissions[], int[] grantresults) { //... }
5. Code Demo
The function is very simple, as follows:
- Click a button, if you have the appropriate permissions to the backup address Book operations;
- If there is no corresponding permission, the user is requested permission;
- If the user authorizes the pass, the backup Address book operation is resumed;
- If the user denies authorization, the popup dialog box directs the user to jump to the app Rights Management interface for manual authorization.
The effect is roughly as follows:
Part of the file code:
1. First declare permissions in Androidmanifest.xml
<?xml version= "1.0" encoding= "Utf-8"?><ManifestXmlns:android="Http://schemas.android.com/apk/res/android"Package="Com.xiets.demoapp" ><!--declare all required permissions (including normal and dangerous)--<Uses-permissionAndroid:name="Android.permission.READ_CONTACTS"/><Uses-permissionAndroid:name="Android.permission.READ_EXTERNAL_STORAGE"/><Uses-permissionAndroid:name="Android.permission.WRITE_EXTERNAL_STORAGE"/><Applicationandroid:icon="@mipmap/ic_launcher"Android:label="@string/app_name"Android:theme="@style/apptheme" ><activity android:name=<intent-filter> <action android:name= " Android.intent.action.MAIN "/> <category android:name=" Android.intent.category.LAUNCHER "/> </intent-filter> </activity> </application> </MANIFEST>
2. layout file Activity_main.xml
<?xml version= "1.0" encoding= "Utf-8"?><RelativelayoutXmlns:android="Http://schemas.android.com/apk/res/android"android:layout_width= "match_parent" android:layout_height="match_parent" android:padding= "10DP" > <button android:layout_width="match_parent" android:layout_height=" Wrap_content " android:onclick=" click " android:textsize=" 20sp " android:text=" Backup Address Book "/ ></relativelayout>
3, Mainactivity
Package Com.xiets.demoapp;Import Android. Manifest;Import Android.content.DialogInterface;Import android.content.Intent;Import Android.content.pm.PackageManager;Import Android.net.Uri;Import Android.os.Bundle;Import android.provider.Settings;Import Android.support.annotation.NonNull;Import Android.support.v4.app.ActivityCompat;Import Android.support.v4.content.ContextCompat;Import Android.support.v7.app.AlertDialog;Import android.support.v7.app.AppCompatActivity;Import Android.view.View;Import Android.widget.Toast;/** * One-click Backup Contacts * *@author Xietansheng * *PublicClassMainactivityExtendsappcompatactivity {PrivateStaticFinalint My_permission_request_code =10000;@OverrideProtectedvoidOnCreate (Bundle savedinstancestate) {Super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); }/** * Click the button to save the address Book backup to an external storage device. * * Requires 3 privileges (all dangerous rights): * 1. Read address Book permissions; * 2. Read external memory permissions; * 3. Write external memory permissions. */PublicvoidClick (View view) {/** * 1th Step: Check if you have the appropriate permissions */Boolean isallgranted = checkpermissionallgranted (New string[] {Manifest.permission.READ_CONTACTS, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE});If all of these 3 permissions are owned, the backup code is executed directlyif (isallgranted) {dobackup ();Return }/** * 2nd Step: Request Permission */Multiple permissions are requested at a time, and if other permissions are granted, the activitycompat.requestpermissions will be ignored automatically (ThisNew string[] {Manifest.permission.READ_CONTACTS, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, My_permission_request_code); }/** * Check if you have all the permissions specified */PrivateBooleanCheckpermissionallgranted (string[] permissions) {for (String permission:permissions) {if (Contextcompat.checkselfpermission (This, permission)! = packagemanager.permission_granted) {Returns false directly if one of the permissions is not grantedReturnFalse } }ReturnTrue }/** * 3rd Step: Request permission result return processing */@OverridePublicvoidOnrequestpermissionsresult (int Requestcode, @NonNull string[] permissions, @NonNullInt[] grantresults) {Super.onrequestpermissionsresult (Requestcode, permissions, grantresults);if (Requestcode = = My_permission_request_code) {Boolean isallgranted =TrueDetermine if all permissions have been granted to thefor (int grant:grantresults) {if (Grant! = packagemanager.permission_granted) {isallgranted =FalseBreak } }if (isallgranted) {If all permissions are granted, execute the backup Code dobackup (); }else {The popup dialog box tells the user why the permission is needed and directs the user to manually open the Permissions button Openappdetails () in the application Rights management. } } }/** * 4th step: Back up Address Book operation */PrivatevoidDobackup () {The main purpose of this article is to explain if the dynamic request permission, the specific backup code no longer show, pretend to back up the Toast.maketext (This"Backing Up contacts ...", Toast.length_short). Show ();/** * Open APP details settings */PrivatevoidOpenappdetails () {Alertdialog.builder Builder =New Alertdialog.builder (this); Builder.setmessage ("To back up your address book requires access to contacts and external storage, please grant it to app information, permissions!" "); Builder.setpositivebutton ("Go to Manual Authorization", new Dialoginterface.onclicklistener () { @Override public void OnClick (dialoginterface dialog, int which) {Intent Intent = new Intent (); Intent.setaction (Settings.action_application_details_ SETTINGS); Intent.addcategory (Intent.category_default); Intent.setdata (Uri.parse ("package:" + getpackagename ())); Intent.addflags (Intent.flag_activity_new_task); Intent.addflags (intent.flag_activity_no_history); Intent.addflags (intent.flag_activity_exclude_from_recents); StartActivity (Intent); } }); Builder.setnegativebutton ("Cancel", null); Builder.show ();}}
Data source: 54315674
Get permissions dynamically after Android 6.0