android6.0动态权限管理,小米bug适配

在Android6.0以后开始,对于部分敏感的“危险”权限,需要在应用运行时向用户申请,只有用户允许的情况下这个权限才会被授予给应用。这对于用户来说,无疑是一个提升安全性的做法。那么对于开发者,应该怎么做呢?

Android6.0规定的危险权限有下面这些:
这里写图片描述

但是如果你的编译版本是23或者以上,那么Android Studio就会报出一个错误。及时在Manifest中声明了权限,6.0的机器仍会崩溃,无法获取到权限。
提示我们要进行权限请求。

 // 缺少权限时, 进入权限配置页面
if (Build.VERSION.SDK_INT >= 23) {
   int checkLocalPhonePermission = ActivityCompat.checkSelfPermission(ActivityDetailActivity.this, LOCAL_PERMISSION);
      if (checkLocalPhonePermission != PackageManager.PERMISSION_GRANTED) 
      {                   ActivityCompat.requestPermissions(ActivityDetailActivity.this, new String[]{LOCAL_PERMISSION}, 101);
  return;
  }
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, REQUESTCODE);
这个时候,再重新运行App,会得到下面的一个界面来请求用户权限:
允许:以后不再弹出请求框,直接允许应用获得该权限
拒绝:下次需要时会重新弹出,直到用户选择允许,否则会不断出现
那么问题就来了,如果用户勾选了不再询问并拒绝了请求会怎样呢?答案是以后不会再弹出,并且默认拒绝权限请求,也就是说,应用再也不能获得这个权限,除非用户主动进入应用设置中重新授权。
为了更好的用户体验,可以在用户选择了不再询问和拒绝之后,创建一个AlertDialog来询问用户是否需要重新授予权限,是的话,跳转到应用设置界面。
当我们调用requestPermissions方法的时候,无论成功与否,都会将结果回调给Activity中的onRequestPermissionsResult方法中,我们可以通过重写这个方法来处理结果:
复制代码
@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUESTCODE) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (!shouldShowRequestPermissionRationale(Manifest.permission.CALL_PHONE)) {
                    AskForPermission();
                }
            }
        }
    }
复制代码
先判断请求是否为我们所申请的,接着判断SDK的版本是否高于或等于AndroidM(6.0),如果是,则调用shouldShowRequestPermissionRationale方法来检查权限申请框是否会显示,因为如果用户选择了不再询问,则申请框会不出现,这个方法会返回false,如果申请框没有出现,则创建一个AlertDialog来询问用户:
复制代码

private void AskForPermission() {

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Need Permission!");

        @Override
        public void onClick(DialogInterface dialog, int which) {

        }
    });
    builder.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.setData(Uri.parse("package:" + getPackageName())); // 根据包名打开对应的设置界面
            startActivity(intent);
        }
    });
    builder.create().show();
} 

小米的MIUI对权限自动分配,android 6.0 权限管理拒绝了之后,检测权限时granted 返回仍然0,显示已授予权限。为了解决这个问题,需要对小米及其他第三方定制rom进行适配,方法如下:

关于MIUI 6.0 权限检测,运行时允许,但Appops拒绝 也是不 能访问的
第一步检测运行时权限
第二步检测AppOpsManager 原生权限检查

 // 缺少权限时, 进入权限配置页面
 if (Build.VERSION.SDK_INT >= 23) {
                int checkLocalPhonePermission = ActivityCompat.checkSelfPermission(ActivityDetailActivity.this, LOCAL_PERMISSION);
                if (checkLocalPhonePermission != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(ActivityDetailActivity.this,
                            new String[]{LOCAL_PERMISSION}, 101);
                    return;
                }
                //适配小米机型
                AppOpsManager appOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
                int checkOp = appOpsManager.checkOp(AppOpsManager.OPSTR_FINE_LOCATION, Process.myUid(), getPackageName());
                if (checkOp == AppOpsManager.MODE_IGNORED) {
                    ActivityCompat.requestPermissions(ActivityDetailActivity.this,
                            new String[]{LOCAL_PERMISSION}, 101);
                    return;
                }
            }
同时在回调中也需要另外处理,通过AlertDailog引导用户打开权限设置:
//用户不同意,向用户展示该权限作用
            if (!ActivityCompat.shouldShowRequestPermissionRationale(this, LOCAL_PERMISSION)) {
                AlertDialog dialog = new AlertDialog.Builder(this)
                        .setMessage("签到功能需要定位你目前的位置,不赋予定位权限将无法正常工作!")
                        .setPositiveButton("前往授权", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                // 根据包名打开对应的设置界面
                                intent.setData(Uri.parse("package:" + getPackageName()));
                                startActivity(intent);
                            }
                        })
                        .setNegativeButton("取消授权", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {

//                                    finish();
                            }
                        }).create();
                dialog.show();
                return;
            }

“`

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值