Android6.0的权限系统

Android6.0棉花糖,app将不会在安装的时候授予权限。取而代之,app不得不在运行的时候一个一个询问用户授予权限。

只有在把 targetSdkVersion 23  以上的版本才会出现。

PROTECTION_NORMAL类权限

用户安装或者更新应用是,系统将授予应用所请求的 PROTECTION_NORMAL的所有权限(安装时授予的一类基本权限)。这类权限包括:
android.permission.ACCESS_LOCATION_EXTRA_COMMANDSandroid.permission.ACCESS_NETWORK_STATEandroid.permission.ACCESS_NOTIFICATION_POLICYandroid.permission.ACCESS_WIFI_STATEandroid.permission.ACCESS_WIMAX_STATEandroid.permission.BLUETOOTHandroid.permission.BLUETOOTH_ADMINandroid.permission.BROADCAST_STICKYandroid.permission.CHANGE_NETWORK_STATEandroid.permission.CHANGE_WIFI_MULTICAST_STATEandroid.permission.CHANGE_WIFI_STATEandroid.permission.CHANGE_WIMAX_STATEandroid.permission.DISABLE_KEYGUARDandroid.permission.EXPAND_STATUS_BARandroid.permission.FLASHLIGHTandroid.permission.GET_ACCOUNTSandroid.permission.GET_PACKAGE_SIZEandroid.permission.INTERNETandroid.permission.KILL_BACKGROUND_PROCESSESandroid.permission.MODIFY_AUDIO_SETTINGSandroid.permission.NFCandroid.permission.READ_SYNC_SETTINGSandroid.permission.READ_SYNC_STATSandroid.permission.RECEIVE_BOOT_COMPLETEDandroid.permission.REORDER_TASKSandroid.permission.REQUEST_INSTALL_PACKAGESandroid.permission.SET_TIME_ZONEandroid.permission.SET_WALLPAPERandroid.permission.SET_WALLPAPER_HINTSandroid.permission.SUBSCRIBED_FEEDS_READandroid.permission.TRANSMIT_IRandroid.permission.USE_FINGERPRINTandroid.permission.VIBRATEandroid.permission.WAKE_LOCKandroid.permission.WRITE_SYNC_SETTINGScom.android.alarm.permission.SET_ALARMcom.android.launcher.permission.INSTALL_SHORTCUTcom.android.launcher.permission.UNINSTALL_SHORTCUT
只需要在AndroidManifest.xml中简单声明这些权限就好,安装时就授权。不需要每次使用时都检查权限,而且用户不能取消以上授权。



让你的app支持新运行时权限

首先在AndroidManifest.xml中声明权限。

下一步,不得不写个方法检查是否有权限。如果没有就弹出对话框询问用户权限

权限分组了。同一组的任何一个权限被授权了,其他权限也自动被授权。源码中用来检查和请求权限的方法是Activity的checkSelfPermission 和requestPermission。这些方法在api23引入




privatevoidinsertDummyContactWrapper(){
    int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS);//检查是否有权限 
    if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},
//请求权限 这个时候会弹出 允许次权限的对话框
REQUEST_CODE_ASK_PERMISSIONS); return; } insertDummyContact(); }


如果已有权限,insertDummyContact()会执行。否则,requestPermissions被执行来弹出请求授权对话框,如下:

 
  

不论用户同意还是拒绝,activity的onRequestPermissionsResult会被回调来通知结果(通过第三个参数),grantResults,如下:

@OverridepublicvoidonRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults){
    switch (requestCode) {
        case REQUEST_CODE_ASK_PERMISSIONS:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission Granted 权限授予
                insertDummyContact();
            } else {
                // Permission Denied
                Toast.makeText(MainActivity.this, "WRITE_CONTACTS Denied", Toast.LENGTH_SHORT)
                        .show();
            }
            break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}


处理 “不再提醒”

如果用户拒绝某授权。下一次弹框,用户会有一个“不再提醒”的选项的来防止app以后继续请求授权。
 
  

如果这个选项在拒绝授权前被用户勾选了。下次为这个权限请求requestPermissions时,对话框就不弹出来了,结果就是,app啥都不干。
这将是很差的用户体验,用户做了操作却得不到响应。这种情况需要好好处理一下。在请求requestPermissions前,我们需要检查是否需要展示请求权限的提示通过activity的
shouldShowRequestPermissionRationale,代码如下:

finalprivateint REQUEST_CODE_ASK_PERMISSIONS = 123;

privatevoidinsertDummyContactWrapper(){
    int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS);
    if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
            if (!shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) {
                showMessageOKCancel("You need to allow access to Contacts",
                        new DialogInterface.OnClickListener() {
                            @OverridepublicvoidonClick(DialogInterface dialog, int which){
                                requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},
                                        REQUEST_CODE_ASK_PERMISSIONS);
                            }
                        });
                return;
            }
        requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},
                REQUEST_CODE_ASK_PERMISSIONS);
        return;
    }
    insertDummyContact();
}
privatevoidshowMessageOKCancel(String message, DialogInterface.OnClickListener okListener){
    new AlertDialog.Builder(MainActivity.this)
            .setMessage(message)
            .setPositiveButton("OK", okListener)
            .setNegativeButton("Cancel", null)
            .create()
            .show();
}


当一个权限第一次被请求和用户标记过不再提醒的时候,我们写的对话框被展示。
后一种情况,onRequestPermissionsResult 会收到PERMISSION_DENIED ,系统询问对话框不展示。


转载 http://www.jianshu.com/p/e1ab1a179fbb

你可能感兴趣的:(Android6.0的权限系统)