Android 6.0 动态权限获取及弹窗提示

Posted on By Qinggai Huang

Android 动态权限获取

动态权限获取

android 6.0(sdk < 23)之前版本会在应用安装时提供一个应用权限列表,用户允许了就可以使用该项权限了。
android 6.0(sdk >= 23)及之后的版本,某些权限需要动态获取。也就是AndroidManifest.xml中申请了之后还不够,还需要在使用该权限的时候去动态获取用户允许。
动态获取权限比较简单,以下以获取ACCESS_COARSE_LOCATION为例子。
此处使用Android支持库检查权限,而不是版本比对。
动态请求权限:

    protected void checkBleScan() {
        if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // Android M Permission check
            ActivityCompat.requestPermissions(this,
                    new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION},
                    REQUEST_CODE_COARSE_LOCATION);
        } else {
            startBleScan();
        }
    }

动态请求权限回调:

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case REQUEST_CODE_COARSE_LOCATION:
                if (grantResults.length > 0 
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    startBleScan();
                } else if (grantResults.length > 0 
                        && grantResults[0] == PackageManager.PERMISSION_DENIED) {
                    if (ActivityCompat.shouldShowRequestPermissionRationale(this, 
                            android.Manifest.permission.ACCESS_COARSE_LOCATION)) {
                        //位置1
                        //用户选择了禁止权限
                        //此处可以进行解释需要该权限的原因
                        LogUtil.d("Show permission explanation dialog");
                    } else {
                        //位置2
                        //用户选择了禁止权限,且勾选了不再弹出权限弹窗
                        //anyway,只能提示用户跳设置页打开权限了
                        LogUtil.e("device not support or Never ask again selected");
                    }
                }
                break;
                default:
                    break;
        }
    }

动态请求权限的弹窗提示

以上代码应该比较简单易懂,比较有意思的一个函数是shouldShowRequestPermissionRationale。这个函数我的理解应该是:

true: 之前用户拒绝过,并且没有在权限请求系统对话框中选择了 Don't ask again 选项。

这个官网有说明,但是不够显眼,哈哈哈!
因此,比较好的利用这个函数的弹窗位置应该是请求权限的回调里面。这个时候用户必定请求过一次了。
上述例子位置1就是用户拒绝了,没有选择 Don't ask again 选项,可以提示用户权限的意义。位置2是用户拒绝了,并且选择了 Don't ask again 选项,这个时候就没有必要弹提示窗了,除非直接引导用户进设置页面开启权限。

参考来源

1、https://developer.android.com/guide/topics/connectivity/bluetooth
2、https://stackoverflow.com/questions/32347532/android-m-permissions-confused-on-the-usage-of-shouldshowrequestpermissionrati
3、https://medium.com/androiddevelopers/picking-your-compilesdkversion-minsdkversion-targetsdkversion-a098a0341ebd