Android6.0 权限管理学习

1、前言

Android M 开始,App不会在安装的时候授予权限,而是在运行时一个一个的询问用户授予权限。html

1. 运行时权限仅当咱们设置targetSdkVersion >= 23才起做用,固然还要是M系统的手机。app在6.0以前的设备依然使用旧的权限系统。java

2. 若是app的targetSdkVersion < 23,或者手机版本  < 6.0 ,那将被认为app没有用23新权限测试过,那将被继续使用旧有规则:用户在安装的时候不得不接受全部权限,安装后app就有了那些权限咯!android

注意,此时用户依然能够取消已经赞成的受权!用户取消受权时,android 6.0系统会警告,但这不妨碍用户取消受权。app

当咱们在targetSdkVersion 低于23的App调用一个须要权限的函数时,这个权限若是被用户取消受权了的话,不抛出异常。可是他将啥都不干,结果致使函数返回值是null或者0。ide

2、官网流程翻译函数

官网:https://developer.android.com/training/permissions/index.html测试

1. Declaring Permissions 声明权限

 在AndroidManifest.xml中声明this

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.snazzyapp">

    <uses-permission android:name="android.permission.SEND_SMS"/>

    <application ...>
        ...
    </application>
</manifest>

权限分正常和危险两种,正常的权限和之前同样,只须要在Manifest.xml中声明便可,在App安装时,自动分配权限,且用户也不能够在设置中取消权限;危险权限须要运行时申请。spa

权限组,将危险权限分组,同一个组里的任何一个权限被受权了,其余权限也自动被受权。翻译

下面是权限表格

Permission Group Permissions
CALENDAR
CAMERA
CONTACTS
LOCATION
MICROPHONE
PHONE
SENSORS
SMS
STORAGE

 

2. Requesting Permissions at Run Time 运行时申请权限

(1)  检测是否已经受权

/**
  * Determine whether <em>you</em> have been granted a particular permission.
  *
  * @param permission The name of the permission being checked.
  *
  * @return {@link PackageManager#PERMISSION_GRANTED} if you have the
  * permission, or {@link PackageManager#PERMISSION_DENIED} if not.
  *
  * @see PackageManager#checkPermission(String, String)
  * @see #checkCallingPermission(String)
  */
checkSelfPermission(String)

(2) 请求权限

shouldShowRequestPermissionRationale() 判断是否须要为权限申请向用户友好提示

返回true,上次申请权限,用户选择拒绝。

返回false

第一次申请,或上次申请权限,用户选择拒绝,并选择了“不在提醒”的选项;

设备的策略禁止当前应用获取这个权限的受权。

注意:第二次请求权限时,才会有“不在提醒”的选项,若是用户一直拒绝,并无选择“不在提醒”的选项,下次请求权限时,会继续有“不在提醒”的选项。

显示权限说明:是根据你的应用中使用的权限分类来的:

1.用户容易知道应用须要获取的权限:如一个拍照应用,须要摄像头的权限,是很正常,不用提示。

2.一些用户感受困惑的一些权限:如:分享图片,还须要获取位置的权限,这个须要提示用户:为何须要这个权限。

处理 “再也不提醒”

若是用户拒绝某受权。下一次弹框,用户会有一个“再也不提醒”的选项的来防止app之后继续请求受权。

若是这个选项在拒绝受权前被用户勾选了。下次为这个权限请求requestPermissions时,对话框就不弹出来了,结果就是,app啥都不干。
这将是不好的用户体验,用户作了操做却得不到响应。这种状况须要好好处理一下。

final private int REQUEST_CODE_ASK_PERMISSIONS = 123;
 
private void insertDummyContactWrapper() {
    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() {
                            @Override
                            public void onClick(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();
}

(3) 处理请求返回结果

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

3. Permissions Best Practices 权限申请最佳实践

1. 若是不须要对数据有特别的控制权的话,能够采起用Intent呼起系统应用的方式来避免申请权限,好比Camera、contacts、phone call,都是能够直接调用系统app的。

注意打电话操做虽然是用的Intent方式,若是是这样的写法context.startActivity(new Intent("android.intent.action.CALL", Uri.parse(formatter.format(tel)))); 也要申请权限;若是是用的 android.intent.action.DIAL来调起的话,就不须要。

2. 只申请须要的权限,且只在须要的时候申请。

相关文章
相关标签/搜索