您的位置:首页 > 移动开发 > Android开发

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

2016-12-31 12:59 375 查看
在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;
}


“`
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: