Marshmallow Version Permissions Modification
The Android privilege system 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 right without the user's knowledge, and the average user rarely has to look at the list of permissions when it's installed, not to get a deeper understanding of the risks associated with these permissions. However, after the Android 6.0 Marshmallow version, the system does not give the app all of its application permissions when the software is installed, and for some dangerous levels of permissions, the app needs to ask the user to grant permission at run time.
Old version app compatibility issues
So the question is, is there a problem with all the previously released apps? The answer is no, only those targetsdkversion set to 23 and above will be abnormal, when using dangerous permissions, the system must obtain the user's consent to use, or the application will crash, a similar error appears.
Java.lang.SecurityException:Permission denial ...
So if Targetsdkversion is not set to 23 or above, the system will still use the old rule: give all the permissions that the app applies to when it's installed. So the app can certainly be as normal as before, but there is a point to note that 6.0 of the system, the user can manually close the app's permissions , in the app info inside the permissions below, you can turn off a permission. If the permissions of the previous application request were manually closed by the user, no exception will be thrown, no crashes, except that the return value of API interfaces that are forbidden by the user is null or 0, so we just need to do a short operation on it, which is to be noted.
General permissions and Dangerous permissions list
Now for the new version of the permission changes should have a basic understanding, then, is not all permissions need to go to special processing it? Of course not, only those dangerous level of authority is required, can 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, against the list, and if you need to apply for one of these permissions, you need to do something special. There's a more humane place to be. If any one of the permissions in the same group is authorized, the other permissions are automatically authorized. For example, once write_external_storage is authorized, the app also has read_external_storage permissions.
Support Marshmallow new version permission mechanism
In the Android M API, we can detect whether the software has a certain permission through checkselfpermission and use Requestpermissions to request a set of permissions.
int haswritecontactspermission = checkselfpermission (Manifest.permission.WRITE_EXTERNAL_STORAGE); 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 permission to write files, and if there is no permission to write the file, the process of requesting permission is initiated by Requestpermissions to the user. After the request is made to the user, the request completes with a corresponding callback method that informs the software user whether the permission was granted. By overriding 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) {// user agrees to write file } else { // User does not agree, self-processing can}}}
Handling no More reminders
If the user has denied authorization for a permission once. The next time the box is played, the user will have a "no longer alert (never ask again)" option to prevent the app from continuing to request authorization later.
If this option is checked by the user before the authorization is denied. The next time for this permission to request Requestpermissions, the dialog box will not pop out, the system will directly callback the Onrequestpermissionsresult function, the callback result is the last user's choice. So in response to this, the system provides a shouldshowrequestpermissionrationale () function that helps developers find situations where they need to explain their permissions to the user in an additional way.
- Apply the first access after installation, directly return false;
- The first time the permission is requested, the user rejects, the next time Shouldshowrequestpermissionrationale () returns True, this can show some explanation of why this permission is required;
- The second time the permission is requested, the user rejects, and the option "no longer reminded" is selected: Shouldshowrequestpermissionrationale () returns false;
- The device's system settings prohibit the current app from obtaining authorization for this permission, Shouldshowrequestpermissionrationale () returns false;
Note: The second time you request permission, there will be a "no longer alert" option, if the user has been refused, and did not select the "no longer remind" option, the next time the permission is requested, will continue to have "no reminder" option, and Shouldshowrequestpermissionrationale ( ) will also always return true.
So with this function we can do the corresponding optimization, there are two ways to return false for the Shouldshowrequestpermissionrationale function:
- If the application is the first time the permission is requested, then call the Requestpermissions function directly to request permission, if not on behalf of the user ticked ' no reminder ', pop-up dialog, tell the user why you need this permission, let the user manually open the permission. Links: http://stackoverflow.com/questions/32347532/ Android-m-permissions-confused-on-the-usage-of-shouldshowrequestpermissionrati
- In the Onrequestpermissionsresult function, if the permission_denied is returned, the Shouldshowrequestpermissionrationale function is called, If the return false means that the user has disabled the permission (3 and 42 cases above), pop-up dialog tells the user why you need the permission and lets the user open it manually. Links: Http://stackoverflow.com/questions/30719047/android-m-check-runtime-permission-how-to-determine-if-the-user-checked-nev
The processing method is already in place, modify the code, here the second scenario to deal with:
@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 { //user does not agree, Show the user the permission action if (!shouldshowrequestpermissionrationale (this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { Showpermissiondialog (); return;}}}
When the tick is no longer reminded and rejected, pop-up dialog to remind the user of the importance of this privilege
Using the Compatibility library
The above code in the 6.0 version of the use of no problem, but before there is a problem, the most simple and rough solution may be the use of Build.VERSION.SDK_INT >= 23 judgment statement to judge, convenient is the SDK 23 of the V4 packages are joined by specialized classes for related processing:
- Contextcompat.checkselfpermission () The Authorized function returns permission_granted, otherwise returns permission_denied, which is true for all versions.
- Activitycompat.requestpermissions () This method is called before 6.0, Onrequestpermissionsresultcallback is called directly, with the correct permission_ Granted or permission_denied.
- Activitycompat.shouldshowrequestpermissionrationale () is called before 6.0 and returns false forever.
There is no need to judge the system version int haswritecontactspermission = Contextcompat.checkselfpermission (Getapplication () using the Compatibility library, Manifest.permission.WRITE_EXTERNAL_STORAGE); if (haswritecontactspermission = = packagemanager.permission_granted) { }//need to eject dialog to let the user manually give permission to else { activitycompat.requestpermissions (acivity.this, New string[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE}, code_for_write_permission);}
The Onrequestpermissionsresult function does not change. The latter two methods can also be used in fragment, with the V13 Compatibility Pack: Fragmentcompat.requestpermissions () and Fragmentcompat.shouldshowrequestpermissionrationale () is the same as the activity effect.
Request multiple permissions at once
Of course, multiple permissions are sometimes required, and multiple permissions can be requested one time using the method above. Of course, the most important thing is not to forget to check the "No reminder" setting for each permission.
list<string> permissionsneeded = new arraylist<string> ();p Ermissionsneeded.add ( Manifest.permission.ACCESS_FINE_LOCATION);p Ermissionsneeded.add (Manifest.permission.READ_CONTACTS); Permissionsneeded.add (Manifest.permission.WRITE_CONTACTS); Requestpermissions (Permissionsneeded.toarray (new String[permissionslist.size ()]), code_for_multiple_permission);
Finally, the Onrequestpermissionsresult function is processed to return the result.
Third-party Library simplified Code
Of course, there are third-party libraries to help with these things:
The open source project on GitHub is permissionhelper,permissionsdispatcher,easypermissions.
The app is in the running state, revoked the permission
What happens if the app is running and the user goes to the Settings-application page to manually revoke the app permissions? The system then pops up the Permission Request dialog box.
Over
New run-time permissions are already in use in cotton candy. We have no retreat. The only thing we can do now is make sure the app is adapting to the new permissions model. Thankfully, only a few permissions require a run-time permission model. Most commonly used permissions, such as network access, that belong to normal Permission are automatically authorized at the time of installation, and of course you want to declare that you do not need to check later. Therefore, only a small part of the code you need to modify.
Two recommendations:
1. Take the new permissions model seriously.
2. If your code does not support new permissions, do not set targetsdkversion 23. Especially when you're building a new project in studio, don't forget to change it!
Talk about code modifications. This is a big deal, and if the code structure is not well designed, you need some very painful refactoring. Each app has to be fixed. As mentioned above, we have no choice. List all the circumstances in which you need to request permission, if A is authorized, B is rejected, what happens, and is handled carefully for each situation.
Android 6.0 permission permissions and security mechanisms