Android 6.0,代号棉花糖,主要新增特性时增加权限限制
权限的分组
Android中有很多权限,但并非所有的权限都是敏感权限,于是6.0系统就对权限进行了分类,主要有4类
正常(Normal Protection)权限:
对用户隐私没有较大影响或者不会打来安全问题
安装后就赋予这些权限, 不需要显示提醒用户,用户也不能取消这些权限
危险(Dangerous)权限:
危险权限实际上才是运行时权限主要处理的对象,这些权限可能引起隐私问题或者影响其他程序运行
Android中的危险权限可以归为以下几个分组:
CALENDAR
CAMERA
CONTACTS
LOCATION
MICROPHONE
PHONE
SENSORS
SMS
STORAGE
模版代码:
private static final int REQUEST_CODE = 1;
private void requestCameraPermission() {
if (
Build.VERSION.SDK_INT < Build.VERSION_CODES.M || ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
// DOTO
} else {
ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.CAMERA}, REQUEST_CODE);// 此处可批量申请
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_CAMERA:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// DOTO
} else {
ToastUtil.showShortToast(context, "申请照相机拍照权限失败,请在系统设置中重新申请");
}
break;
}
}
注:1> 间隔较短的多个权限申请建议设置成单次多个权限申请形式,避免弹出多个对话框,造成不太好的视觉效果
2> 不需要每个权限都去显式申请,举一个例子,如果你的应用授权了读取联系人的权限,那么你的应用也是被赋予了写入联系人的权限。因为读取联系人和写入联系人这两个权限都属于联系人权限分组,所以一旦组内某个权限被允许,该组的其他权限也是被允许的
3> 由于checkSelfPermission和requestPermissions从API 23才加入,低于23版本,需要在运行时判断 或者使用Support Library v4中提供的方法
ContextCompat.checkSelfPermission
ActivityCompat.requestPermissions
ActivityCompat.shouldShowRequestPermissionRationale
4> 支持了6.0必须也要支持4.4,5.0这些系统,所以需要在很多情况下,需要有两套处理。比如Camera权限
if (isMarshmallow()) {
requestPermission();//然后在回调中处理
} else {
useCamera();//低于6.0直接使用Camera
}
特殊(Particular)权限:
一些特别敏感的权限,在Android系统中,主要由两个
<1> SYSTEM_ALERT_WINDOW,设置悬浮窗,进行一些黑科技,模版代码:
private static final int REQUEST_CODE = 1;
private void requestAlertWindowPermission() {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); // 启动隐式Intent
intent.setData(Uri.parse("package:" + getPackageName())); // 携带App的包名信息
startActivityForResult(intent, REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE) {
if (Settings.canDrawOverlays(this)) { // 判断授权结果
Log.i(LOGTAG, "onActivityResult granted");
}
}
}
<2> WRITE_SETTINGS 修改系统设置,模版代码:
private static final int REQUEST_CODE_WRITE_SETTINGS = 2;
private void requestWriteSettings() {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); // 启动隐式Intent
intent.setData(Uri.parse("package:" + getPackageName())); // 携带App的包名信息
startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS );
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_WRITE_SETTINGS) {
if (Settings.System.canWrite(this)) { // 方法检测授权结果
Log.i(LOGTAG, "onActivityResult write settings granted" );
}
}
}
其他权限(一般很少用到):