版权声明:个人原创,欢迎转载。 https://blog.csdn.net/chuyangchangxi/article/details/86235572
一、目标
动态申请运行时权限。
1. 效果图
- 左侧,告知用户权限的用途
- 右侧,引导用户手动设置权限
2. 下载地址
神马笔记最新版本:【神马笔记 版本1.2.0.apk】
二、功能设计
从Android 6.0(API 23)开始后,部分权限除了需要在AndroidManifest.xml中声明外,还必须在运行时动态申请,比如WRITE_EXTERNAL_STORAGE
。
因此,涉及到运行时权限相关API时,首先要确保用户授予了应用相应的权限,才能继续执行之后的操作。
三、准备工作
时间紧,任务重。
直接使用第三方开源库来解决这个问题。我们将使用RxPermissions来实现这个功能。
GitHub项目地址:https://github.com/tbruyelle/RxPermissions
四、组合起来
1. PermissionHelper
对RxPermissions做了简单封装,对应三种情况分别做了处理。
扫描二维码关注公众号,回复:
4869170 查看本文章
- 已经授予权限,通过回调继续之后操作
- 需要显示申请,弹出对话框告知用户,并再次请求权限
- 用户拒绝授权,弹出对话框告知用户,并跳转到应用设置手动开启权限
目前仅支持一种权限,多权限申请可以在这基础上进行扩展。
并且整理了一些国内手机厂商如小米、魅族、华为直接进入权限设置的方式。
(小米测试可用,魅族、华为未进行测试。)
public class PermissionHelper {
String mPermission;
CharSequence mRequestMsg;
CharSequence mDeniedMsg;
FragmentActivity mContext;
OnPermissionListener mOnPermissionListener;
public PermissionHelper(FragmentActivity context) {
this.mContext = context;
this.mPermission = Manifest.permission.WRITE_EXTERNAL_STORAGE;
this.mRequestMsg = "";
this.mDeniedMsg = "";
}
public PermissionHelper setPermission(String permission) {
this.mPermission = permission;
return this;
}
public PermissionHelper setRequestMessage(CharSequence text) {
this.mRequestMsg = text;
return this;
}
public PermissionHelper setDeniedMessage(CharSequence text) {
this.mDeniedMsg = text;
return this;
}
public PermissionHelper setOnPermissionListener(OnPermissionListener listener) {
this.mOnPermissionListener = listener;
return this;
}
public void request() {
RxPermissions rxPermission = new RxPermissions(mContext);
rxPermission.requestEach(mPermission).subscribe(this::accept);
}
void accept(Permission permission) {
if (permission.granted) {
// 用户已经同意该权限
if (mOnPermissionListener != null) {
mOnPermissionListener.onPermissionGranted(this);
}
} else if (permission.shouldShowRequestPermissionRationale) {
// 用户拒绝了该权限,没有选中『不再询问』(Never ask again),那么下次再次启动时,还会提示请求权限的对话框
DialogInterface.OnClickListener listener = (dialog, which) -> {
if (which == DialogInterface.BUTTON_POSITIVE) {
request();
} else if (which == DialogInterface.BUTTON_NEGATIVE) {
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setMessage(mRequestMsg);
builder.setPositiveButton(android.R.string.yes, listener);
builder.setNegativeButton(android.R.string.cancel, listener);
AlertDialog dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
dialog.show();
} else { // 用户拒绝了该权限,并且选中『不再询问』
DialogInterface.OnClickListener listener = (dialog, which) -> {
if (which == DialogInterface.BUTTON_POSITIVE) {
showSetting(mContext);
} else if (which == DialogInterface.BUTTON_NEGATIVE) {
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setMessage(mDeniedMsg);
builder.setPositiveButton(android.R.string.yes, listener);
builder.setNegativeButton(android.R.string.cancel, listener);
AlertDialog dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
dialog.show();
}
}
static void showSetting(Context context) {
if (gotoMiuiPermission(context)) {
return;
}
if (gotoMeizuPermission(context)) {
return;
}
if (gotoHuaweiPermission(context)) {
return;
}
if (gotoAppDetailSetting(context)) {
return;
}
}
static boolean gotoMiuiPermission(Context context) {
// MIUI 8
try {
Intent localIntent = new Intent("miui.intent.action.APP_PERM_EDITOR");
localIntent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity");
localIntent.putExtra("extra_pkgname", context.getPackageName());
context.startActivity(localIntent);
return true;
} catch (Exception e) {
}
// MIUI 5/6/7
try {
Intent localIntent = new Intent("miui.intent.action.APP_PERM_EDITOR");
localIntent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
localIntent.putExtra("extra_pkgname", context.getPackageName());
context.startActivity(localIntent);
return true;
} catch (Exception e1) {
}
return false;
}
static boolean gotoMeizuPermission(Context context) {
try {
Intent intent = new Intent("com.meizu.safe.security.SHOW_APPSEC");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
context.startActivity(intent);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
static boolean gotoHuaweiPermission(Context context) {
try {
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ComponentName comp = new ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity");//华为权限管理
intent.setComponent(comp);
context.startActivity(intent);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
static boolean gotoAppDetailSetting(Context context) {
Intent localIntent = new Intent();
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= 9) {
localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
localIntent.setData(Uri.fromParts("package", context.getPackageName(), null));
} else if (Build.VERSION.SDK_INT <= 8) {
localIntent.setAction(Intent.ACTION_VIEW);
localIntent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails");
localIntent.putExtra("com.android.settings.ApplicationPkgName", context.getPackageName());
}
try {
context.startActivity(localIntent);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
*
*/
public interface OnPermissionListener {
void onPermissionGranted(PermissionHelper helper);
}
}
五、Final
RxPermissions工作良好,没有机会探究Android运行时权限的相关代码。
~幸甚至哉~幸甚至哉~