Android 6.0 Permission and security mechanism, androidpermission
Modify Marshmallow version Permissions
The permission system of android has always been the primary security concept, because these permissions are only asked once during installation. Once installed, the app can access everything in the permission without the user's knowledge. Generally, when installing the app, the user seldom looks at the permission list carefully, do not go into the potential harm of these permissions. However, after the android 6.0 release mallow version, the system will not grant all the permissions applied for by the app during software installation. For some dangerous permissions, the app needs to ask the user to grant permissions one by one during running.
Compatibility with old apps
So the question is, is there a problem with all previously released apps? The answer is no. Only applications whose targetSdkVersion is set to 23 or above will encounter exceptions. The system must obtain the user's consent to use dangerous permissions, otherwise, the application will crash and an error similar to the following will occur.
java.lang.SecurityException: Permission Denial...
Therefore, if targetSdkVersion is not set to Version 23 or later, the system will still use the old rule: grant all permissions applied for by the app during installation. So of course, the app can be used normally as before, but it should be noted that in the 6.0 system,You can manually disable the permissions of the app.Under Permissions in App info, you can disable a permission. If the permissions applied for by the old application have been manually disabled by the user, no exception is thrown and no crash occurs, but the returned values of api interfaces that are forbidden by the user are both null or 0, therefore, we only need to perform the empty search operation. This is worth noting.
List of common and dangerous Permissions
Now I have a basic understanding of the new version of permission change. Do I have to deal with all permissions? Of course not. Only dangerous permissions are required. For details, refer to the official website.
Http://developer.android.com/training/permissions/requesting.html
Http://developer.android.com/guide/topics/security/permissions.html#normal-dangerous
So take a closer look at your app and compare it to the list. If you need to apply for one of the permissions, You need to perform special operations. In addition, if any permission in the same group is authorized, other permissions are automatically authorized. For example, once WRITE_EXTERNAL_STORAGE is authorized, the app also has the READ_EXTERNAL_STORAGE permission.
Support permission mechanisms for new versions of Marshmallow
In the Android M api, we can use checkSelfPermission to check whether the software has a certain permission and use requestPermissions to request a group of permissions.
int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, CODE_FOR_WRITE_PERMISSION); return;}
The code block above shows whether the software has the permission to write files. If you do not have the permission to write files, you can use requestPermissions to send a request permission to the user. After a request is sent to the user, a corresponding callback method is provided to notify the software user whether the permission is granted. Override the onRequestPermissionsResult method in Activity or Fragment.
@ Overridepublic void onRequestPermissionsResult (int requestCode, String [] permissions, int [] grantResults) {if (requestCode = CODE_FOR_WRITE_PERMISSION) {if (permissions [0]. equals (Manifest. permission. WRITE_EXTERNAL_STORAGE) & grantResults [0] = PackageManager. PERMISSION_GRANTED) {// The User agrees to write the file} else {// the user does not agree, you can handle it yourself }}}
No reminder for handling
If a user rejects authorization for a certain permission. In the next dialog box, the user will have an option "no longer remind (Never ask again)" to prevent the app from continuing to request authorization in the future.
If this option is selected by the user before the authorization is denied. The next time you request requestPermissions for this permission, the dialog box will not pop up. The system will directly call back the onRequestPermissionsResult function and the callback result will be the last user selection. To cope with this situation, the system provides a shouldShowRequestPermissionRationale () function, which helps developers find situations where they need to explain additional permissions to users.
Note: The "no longer reminder" option is available only when the second request is submitted. If the user refuses, the "no longer reminder" option is not selected, the option "no longer reminder" will continue, and shouldShowRequestPermissionRationale () will always return true.
Therefore, we can use this function to optimize it accordingly. There are two methods for processing the shouldShowRequestPermissionRationale function to return false:
- If the application requests this permission for the first time, it directly calls the requestPermissions function to request the permission. If not, it indicates that the user has checked "no longer reminded". A dialog box is displayed to show you why you need this permission, allow the user to manually enable the permission. Link: http://stackoverflow.com/questions/32347532/android-m-permissions-confused-on-the-usage-of-shouldshowrequestpermissionrati
- Checks the onRequestPermissionsResult function. If PERMISSION_DENIED is returned, the shouldShowRequestPermissionRationale function is called. If false is returned, the user has disabled the permission (in the preceding 3 and 4 cases ), the pop-up dialog tells the user why the permission is required and allows the user to open it manually. Link: http://stackoverflow.com/questions/30719047/android-m-check-runtime-permission-how-to-determine-if-the-user-checked-nev
The solution already exists. modify the code and use the second solution to handle it:
@ Overridepublic void onRequestPermissionsResult (int requestCode, String [] permissions, int [] grantResults) {if (requestCode = CODE_FOR_WRITE_PERMISSION) {if (permissions [0]. equals (Manifest. permission. WRITE_EXTERNAL_STORAGE) & grantResults [0] = PackageManager. PERMISSION_GRANTED) {// user consent} else {// the user does not agree, show the role of this permission to the user if (! ShouldShowRequestPermissionRationale (this, Manifest. permission. WRITE_EXTERNAL_STORAGE) {showPermissionDialog (); return ;}}}}
If you do not receive a notification when you select this option, a dialog box is displayed to remind you of the importance of this permission.
Use compatible Libraries
The above code is used in version 6.0, but there is a problem before. The simplest and most crude solution may be to use Build. VERSION. SDK_INT> = 23: This judgment statement makes it easy to add the v4 package of SDK 23 to a specialized class for related processing:
- ContextCompat. checkSelfPermission () is returned by the authorization function PERMISSION_GRANTED; otherwise, PERMISSION_DENIED is returned, which is true for all versions.
- ActivityCompat. requestPermissions () is called in versions earlier than 6.0. OnRequestPermissionsResultCallback is called directly with the correct PERMISSION_GRANTED or PERMISSION_DENIED.
- ActivityCompat. shouldShowRequestPermissionRationale () is called in versions earlier than 6.0, and false is always returned.
// Using the compatible library, you do not need to judge the system version int hasWriteContactsPermission = ContextCompat. checkSelfPermission (getApplication (), Manifest. permission. WRITE_EXTERNAL_STORAGE); if (hasWriteContactsPermission = PackageManager. PERMISSION_GRANTED) {}// you need to bring up the dialog so that you can manually grant else {ActivityCompat. requestPermissions (Acivity. this, new String [] {Manifest. permission. WRITE_EXTERNAL_STORAGE}, CODE_FOR_WRITE_PERMISSION );}
The onRequestPermissionsResult function remains unchanged. The last two methods can also be used in Fragment. Use the v13 compatibility package: FragmentCompat. requestPermissions () and FragmentCompat. shouldShowRequestPermissionRationale.
Multiple permissions are requested at a time.
Of course, you can use the preceding method to request Multiple permissions at a time. Of course, the most important thing is not to forget to check the "no longer reminder" setting for each permission.
List<String> permissionsNeeded = new ArrayList<String>();permissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);permissionsNeeded.add(Manifest.permission.READ_CONTACTS);permissionsNeeded.add(Manifest.permission.WRITE_CONTACTS);requestPermissions(permissionsNeeded.toArray(new String[permissionsList.size()]), CODE_FOR_MULTIPLE_PERMISSION);
Finally, you can process the returned results in the onRequestPermissionsResult function.
Third-party library simplified code
Of course, we already have a third-party library to help with these tasks:
Open-source projects on Github: PermissionHelper, PermissionsDispatcher, and EasyPermissions.
The permission is revoked when the APP is running.
If the APP is running, the user will go to settings-application page to manually revoke the APP permission. What will happen? The system then displays the permission request dialog box.
Over
The new runtime permission has been used in marshmallow. We have no way back. The only thing we can do now is ensure that the app adapts to the new permission model. Fortunately, only a few permissions require the runtime permission model. Most common permissions, such as network access, belong to Normal Permission and are automatically authorized during installation. Of course, you need to declare them and do not need to check them later. Therefore, you only need to modify a small amount of code.
Two suggestions:
1. Take the new permission model seriously.
2. If your code does not support new permissions, do not set targetSdkVersion 23. Especially when you create a project in Studio, do not forget to modify it!
Let's talk about code modification. This is a big deal. If the code structure is not well designed, you need some tough refactoring. Each app must be modified. As mentioned above, we have no choice. List all the situations where you need to request permissions. If A is authorized and B is denied, what will happen? Take care of each situation.