Android运行时权限分析

一、前言:
首先,来讲一讲运行时权限。从Android 6.0开始,Google引入了运行时权限。Android中的权限分为两类:Normal Permission和Dangerous Permission。Normal Permission(即普通权限,一般不涉及到用户隐私),比如访问网络、手机震动等等;Dangerous Permission(一般涉及到用户隐私),比如读取sdcard、拨打电话、访问通讯录等等。

从Android 6.0开始,对于Dangerous Permission,是需要用户授权的,仅仅在AndroidManifest中声明权限是不管用的。

二、相关API:
1、ContextCompat.checkSelfPermission(Context context, String permission)
主要用来检测某个权限是否已经被授权
方法的返回值为PackageManager.PERMISSION_GRANTED或者PackageManager.PERMISSION_DENIED
当返回值为PackageManager.PERMISSION_DENIED就需要进行申请授权了。

2、ActivityCompat.requestPermissions(Activity activity, String[] permissions, int requestCode)
申请授权
第一个参数是Activity实例
第二个参数是需要申请的权限的字符串数组
第三个参数是requestCode,主要用于回调的时候检测
该方法是支持一次性申请多个权限的,系统会通过对话框逐一询问用户是否授权

3、onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults)
处理权限申请回调

4、ActivityCompat.shouldShowRequestPermissionRationale(Activity activity, String permission)
这个API主要用于给用户一个申请权限的解释

三、例子:
我们拿拨打电话举例。
1、在AndroidManifest.xml中声明权限:

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

2、

public void testCall(Context context, String phoneNumber) {
        /**
         * 这里要处理一个“允许拨打电话”的运行时权限
         * ContextCompat.checkSelfPermission,主要用来检测某个权限是否已经被授权,
         * 方法返回值为PackageManager.PERMISSION_GRANTED或者PackageManager.PERMISSION_DENIED
         * 当返回DENIED就需要进行申请授权了
         */
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE)
                != PackageManager.PERMISSION_GRANTED) {
            /**
             * ActivityCompat.shouldShowRequestPermissionRationale
             * 这个API主要用于给用户一个申请权限的解释
             */
            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CALL_PHONE)) {
                Toast.makeText(this, "您需要此权限来拨打电话", Toast.LENGTH_SHORT).show();
            }
            /**
             * 申请授权
             * ActivityCompat.requestPermissions
             * 第一个参数是Activity实例
             * 第二个参数是需要申请的权限的字符串数组
             * 第三个参数是requestCode,主要用于回调的时候检测
             *
             * 该方法是支持一次性申请多个权限的,系统会通过对话框逐一询问用户是否授权
             */
            ActivityCompat.requestPermissions(this,
                    new String[] {Manifest.permission.CALL_PHONE},
                    MY_PERMISSIONS_REQUEST_CALL_PHONE);
        } else {
            call(context, phoneNumber);
        }
    }
    /**
     * 处理权限申请回调
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_CALL_PHONE:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    call(this, "10086");
                } else {
                    Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
                }
                break;
            default:
                break;
        }
    }
    /**
     * 拨打电话
     * @param context 上下文对象
     * @param phoneNumber 电话号码
     */
    public void call(Context context, String phoneNumber) {
        context.startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber)));
    }

猜你喜欢

转载自blog.csdn.net/zdj_develop/article/details/75305306