已经有一年多没有写博客了,主要就是忙。自己独立开发的确有点累,很多东西都要自己去脑补,遇到问题也没有可商量的同事,所以只能自己想办法解决。闲话少说,言归正传!
6.0动态权限的申请已经有很长时间了,网上也有很多案例,应某些人要求,这里我只是提供下我自己的见解!
之所以会有动态权限的申请,还是因为android手机做的越来越安全了,也越来越人性化了,同时对开发者来说是越来越麻烦了。有些涉及到用户的隐私的权限,是用户不想让其它应用获取到的(如:定位、联系人、读写文件…)。所以android就把这些关于个人隐私的权限交由用户自己来决定,涉及到的动态权限主要有(下图是从别处复制过来的)
以上权限如果只是在配置清单里面配置是获取不到任何权限的,那么这些权限是如何申请的呢?
/**
* 发起权限请求
*
* @param context
* @param permissions
* @param callback
*/
public void requestPermissions(final Context context, final String[] permissions,
RequestPermissionCallBack callback) {
this.mRequestPermissionCallBack = callback;
List<String> permissionNames = PermissionUtils.transformText(this, Arrays.asList(permissions));
StringBuilder permissionName = new StringBuilder();
for (String s : permissionNames) {
permissionName = permissionName.append(s + "\r\n");
}
//如果所有权限都已授权,则直接返回授权成功,只要有一项未授权,则发起权限请求
boolean isAllGranted = true;
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_DENIED) {
isAllGranted = false;
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, permission)) {
new AlertDialog.Builder(context)
.setMessage("您好,此操作需要如下权限:\r\n" +
permissionName +
" 请允许,否则此操作讲无法进行。")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(((Activity) context), permissions, mRequestCode);
}
}).show();
} else {
ActivityCompat.requestPermissions(((Activity) context), permissions, mRequestCode);
}
break;
}
}
if (isAllGranted) {
mRequestPermissionCallBack.granted();
return;
}
}
在应用被打开需要申请权限,弹出权限申请提示框,被用户不小心点成拒绝或不想给予权限,也就是说我们的权限申请被拒绝了,又该如何操作呢?其实我们申请权限的时候是有一个回调的,告诉我们申请权限的结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
boolean hasAllGranted = true;
List<String> permissionNames = PermissionUtils.transformText(MyBaseAty.this, Arrays.asList(permissions));
StringBuilder permissionName = new StringBuilder();
for (String s : permissionNames) {
permissionName = permissionName.append(s + "\r\n");
}
switch (requestCode) {
case mRequestCode: {
for (int i = 0; i < grantResults.length; ++i) {
if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
hasAllGranted = false;
//在用户已经拒绝授权的情况下,如果shouldShowRequestPermissionRationale返回false则
// 可以推断出用户选择了“不在提示”选项,在这种情况下需要引导用户至设置页手动授权
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) {
new AlertDialog.Builder(this)
.setMessage("您好!由于您选择了不再提示这项操作,导致获取权限失败\r\n" +
"获取相关权限如下:\r\n" +
permissionName +
"请前往设置页面手动授权")
.setPositiveButton("去授权", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getApplicationContext().getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mRequestPermissionCallBack.denied();
}
}).setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
mRequestPermissionCallBack.denied();
}
}).show();
} else {
//用户拒绝权限请求,但未选中“不再提示”选项
mRequestPermissionCallBack.denied();
}
break;
}
}
if (hasAllGranted) {
mRequestPermissionCallBack.granted();
}
}
}
}
关于权限请求接口的回调是自己写的
/**
* 权限请求结果回调接口
*/
public interface RequestPermissionCallBack {
/**
* 同意授权
*/
void granted();
/**
* 取消授权
*/
void denied();
}
有了上面这些代买还是不够的,因为我们上面的代码并没有看到有任何权限出现,其实上面的代码只是实现的一个基类而已,就是方便大家使用的时候可以多处调用,下面以申请读写为例来实现具体的权限申请。其实很简单,请看如下代码
public void requestMultiPermission() {
requestPermissions(this, new String[]{
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE},
new MainAty.RequestPermissionCallBack() {
@Override
public void granted() {
//获取权限成功的操作
}
@Override
public void denied() {
//获取失败的操作
}
});
}
别以为是动态权限就不需要在配置清单里面设置用户权限了,请切记!上面说的不要只是在配置清单里面设置就可以了,并不是说不要再配置清单里面设置权限申请的
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
通过上面的代码是不是感觉动态申请权限其实并没有那么复杂?
效果图如下
点击下载源码