Android运行时权限:

android6.0对权限管理模块进行了修改程序在访问对用户敏感的权限时,不仅在清单文件中配置相应的权限,还需要用代码动态申请。

(了解Android变化的请看官方文档 Android6.0 Changes

首先和之前一样,首先在清单文件里面声明应用要用到的权限:

<uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

检查所需权限

在进行敏感权限操作时,比如读取联系人、向sd卡写文件等,首先要去检测应用是否拥有对应的权限,例如:

// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.WRITE_CALENDAR);

如果app已经有了这个权限,会返回PackageManger.PERMISSION_GRANTED,有权限就可以做相应的操作了;没有权限会返回PERMISSION_DENIED,这个时候就需要app向用户申请对应的权限。

请求需要的权限

如果app没有相应权限,就需要调用requestPermissions()方法去请求相应权限,MY_PERMISSIONS_REQUEST_READ_CONTACTS是一个int类型的请求码,等下在回调方法区分权限申请的请求,有点类似于startActivityForResult()方法,如下是检查app读取联系人的权限,如果没有去请求相应权限的code

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {

    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {

        // Show an expanation 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, we can 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.
    }
}

调用该方法系统会弹出一个申请权限对话框,该对话框不能修改。如下是官网的说明:

Note: When your app calls requestPermissions(), the system shows a standard dialog box to the user. Your app cannot configure or alter that dialog box. If you need to provide any information or explanation to the user, you should do that before you call requestPermissions(), as described in Explain why the app needs permissions.

处理权限请求的回调

当应用申请权限时,系统会弹出权限申请的对话框,当用户赋予或则拒绝了权限,会回调onRequestPermissionResult方法,应用需要覆盖该方法,判断申请的权限是否准许了,该方法的requestCode就是你在requestPermissions传过去的值。如下,如果应用请求了READ_CONTACTS可能需要在onRequestPermissionResult中做如下处理。

@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
    }
}

当然,你也可以一次申请一组权限,系统只会弹出一次对话框,后续请求这个组中的权限,系统会自动准许,需要注意的是权限组在后续的Android版本可能会有调整,大家不能依赖这种方式,每次都应该去申请相应的权限。如下是官方的说明:

Note: Your app still needs to explicitly request every permission it needs, even if the user has already granted another permission in the same group. In addition, the grouping of permissions into groups may change in future Android releases. Your code should not rely on the assumption that particular permissions are or are not in the same group.

更多内容请查看 Working with System Permissions