Android权限在6.0之后有了较大的不同,不再是安装软件之后,就提示用户授予权限,而且6.0之后,google 对于权限的管理也越加严格,对权限进行了分类:1、普通权限,2、危险权限。
1、Android6.0及以上的权限提示
1、其实有去玩过系统为6.0及以上的手机的同学,会发现,新的 api 下的权限提示,是需要自己代码手动去获取授予的。
2、但是如果你项目的 gradle 里面的 targetSdkVersion 的版本并不是最新的版本,你会发现你即便代码去获取权限授予窗口,窗口也是不弹出的,这是 google 兼容低版本的问题,就是说如果你 targetSdkVersion 不是最新,将采用低版本的权限授予方式,不过还是建议大家改为最新。
defaultConfig {
multiDexEnabled true
minSdkVersion 14
targetSdkVersion 25
}
2、判断权限是否授予 或者 拒绝
1、新的 api 提供了对权限是否授予,提供了方法可以判断,大家可以集成到一个 PermissionUtil 的工具类里面,方便使用。
/**
* 判断是否缺少权限集合
* @param permissions 权限数组
*/
public static boolean lacksPermissions(String... permissions) {
for (String permission : permissions) {
if (lacksPermission(permission)) {
return true;
}
}
return false;
}
/**
* 判断是否缺少权限
* @param permission 单个权限
*/
public static boolean lacksPermission(String permission) {
return ContextCompat.checkSelfPermission(BaseApplication.getDefaultApplication().getApplicationContext(), permission) ==
PackageManager.PERMISSION_DENIED;
}
3、对于请求权限的处理
1、我是将请求权限的操作,放到一个单独的 activity 里面,在这个 activity 统一进行权限的请求。具体代码如下:
public class PermissionActivity extends BasicActivity implements ActivityCompat.OnRequestPermissionsResultCallback {
private static final String PERMISSION = "PERMISSION";
private static final String EXPLANATION = "EXPLANATION";
private static final int PERMISSION_ASK_CODE = 10160;
private String message;
private String[] permissions;
public static void requestPermissions(Activity activity, String explanation, int requestCode, String... permissions) {
Intent intent = new Intent(activity, PermissionActivity.class);
intent.putExtra(PERMISSION, permissions);
intent.putExtra(EXPLANATION, explanation);
activity.startActivityForResult(intent, requestCode);
activity.overridePendingTransition(R.anim.no_animation, R.anim.no_animation);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_permission); 不需要布局
permissions = getIntent().getStringArrayExtra(PERMISSION);
message = getIntent().getStringExtra(EXPLANATION);
if (permissions != null && permissions.length > 0) {
askPermission();
} else {
throw new IllegalArgumentException("permissions is null or \"\" ");
}
}
private void askPermission() {
if (PermissionUtil.lacksPermissions(permissions)) {
// // Should we show an explanation?
// if (ActivityCompat.shouldShowRequestPermissionRationale(this,
// permissions)) {
//
// }
rationale();
} else {
allGranted();
}
}
public void allGranted() {
Toast.makeText(this, R.string.grant_success, Toast.LENGTH_SHORT).show();
setResult(RESULT_OK);
finish();
}
public void denied() {
Toast.makeText(this, R.string.grant_fail, Toast.LENGTH_SHORT).show();
setResult(RESULT_CANCELED);
finish();
}
public void rationale() {
AppTextMessageDialogBuilder builder = new AppTextMessageDialogBuilder(this);
builder.setMessage(message);
builder.setPositiveText(getString(R.string.ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
ActivityCompat.requestPermissions(PermissionActivity.this,
permissions,
PERMISSION_ASK_CODE);
}
}
);
builder.create().show();
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
if (requestCode == PERMISSION_ASK_CODE) {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& hasAllPermissionsGranted(grantResults)) {
allGranted();
} else {
denied();
}
}
}
// 含有全部的权限
private boolean hasAllPermissionsGranted(int[] grantResults) {
for (int grantResult : grantResults) {
if (grantResult == PackageManager.PERMISSION_DENIED) {
return false;
}
}
return true;
}
}
2、需要说明的是,对于权限的授予流程,如果用户在权限授予窗口,勾选了 “不在提示” 的勾选框,那么将不再显示授权窗口,之后我们再怎么代码去调用,都不会弹窗的;但如果,用户仅仅是点击了 “取消” 那我们有一次对权限进行解释的机会,就是解释我们要这个权限究竟是做什么用的,还是会弹窗的。
4、开源的权限管理的库
1、一个是我网友joker写的,他在这方面针对国内的一些主要机型,进行了适配和兼容处理,功能还是很强大的。感兴趣的可以看看,GitHub 地址为:https://github.com/jokermonn/permissions4m ;还有一个是鸿洋大神自己分享的开源库,Github 地址为:https://github.com/hongyangAndroid/MPermissions 。