前言
EasyPermissions是检查和申请Android动态权限的库,简化了原生权限逻辑。
使用方法参照官方文档。
一、需求
需要对库里面封装了2个提示弹框替换成app内部统一的设计式样,分别是:
- 提示框1: 用户拒绝权限后提示。
- 提示框2: 用户拒绝权限且选择以后都不再询问时提示,在收到拒绝回调时show出内置的AppSettingsDialog。
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size());
// (Optional) Check whether the user denied any permissions and checked "NEVER ASK AGAIN."
// This will display a dialog directing them to enable the permission in app settings.
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
new AppSettingsDialog.Builder(this).build().show();
}
}
复制代码
点击确定键会跳转到设置中的应用信息方便更改权限
public void onClick(DialogInterface dialog, int which) {
if (which == Dialog.BUTTON_POSITIVE) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.setData(Uri.fromParts("package", getPackageName(), null));
intent.addFlags(mIntentFlags);
startActivityForResult(intent, APP_SETTINGS_RC);
} else if (which == Dialog.BUTTON_NEGATIVE) {
setResult(Activity.RESULT_CANCELED);
finish();
} else {
throw new IllegalStateException("Unknown button type: " + which);
}
}
复制代码
二、实现
- 提示框2很好替换,把AppSettingsDialog替换成自己的Dialog就可以了。
override fun onPermissionsDenied(requestCode: Int, perms: List<String>) {
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
CommonDialog.Builder(this).build().show()
}
}
复制代码
- 提示框1没找到公开能替换的方法。
请求权限时的调用:
private fun requestPermission(vararg perms: String) {
val request = PermissionRequest.Builder(this, REQUEST_CODE_PERMISSIONS, *perms)
.setRationale("This app may not work correctly without the requested permissions.")
.setPositiveButtonText("确定")
.setNegativeButtonText("取消")
.build()
EasyPermissions.requestPermissions(request)
}
复制代码
先看一下源码,通过PermissionRequest的getHelper()取到PermissionHelper,然后调用的requestPermissions方法申请权限
public static void requestPermissions(PermissionRequest request) {
// Check for permissions before dispatching the request
if (hasPermissions(request.getHelper().getContext(), request.getPerms())) {
notifyAlreadyHasPermissions(
request.getHelper().getHost(), request.getRequestCode(), request.getPerms());
return;
}
// Request permissions
request.getHelper().requestPermissions(
request.getRationale(),
request.getPositiveButtonText(),
request.getNegativeButtonText(),
request.getTheme(),
request.getRequestCode(),
request.getPerms());
}
复制代码
PermissionHelper是在创建PermissionRequest时创建的
public Builder(@NonNull Activity activity, int requestCode,
@NonNull @Size(min = 1) String... perms) {
mHelper = PermissionHelper.newInstance(activity);
mRequestCode = requestCode;
mPerms = perms;
}
public Builder(@NonNull Fragment fragment, int requestCode,
@NonNull @Size(min = 1) String... perms) {
mHelper = PermissionHelper.newInstance(fragment);
mRequestCode = requestCode;
mPerms = perms;
}
复制代码
PermissionHelper调用showRequestPermissionRationale显示弹框
public void requestPermissions(@NonNull String rationale,
@NonNull String positiveButton,
@NonNull String negativeButton,
@StyleRes int theme,
int requestCode,
@NonNull String... perms) {
if (shouldShowRationale(perms)) {
showRequestPermissionRationale(
rationale, positiveButton, negativeButton, theme, requestCode, perms);
} else {
directRequestPermissions(requestCode, perms);
}
}
复制代码
PermissionHelper是个抽象类,继承关系如下
找个BaseSupportPermissionsHelper的showRequestPermissionRationale方法看一下
public void showRequestPermissionRationale(@NonNull String rationale,
@NonNull String positiveButton,
@NonNull String negativeButton,
@StyleRes int theme,
int requestCode,
@NonNull String... perms) {
FragmentManager fm = getSupportFragmentManager();
// Check if fragment is already showing
Fragment fragment = fm.findFragmentByTag(RationaleDialogFragmentCompat.TAG);
if (fragment instanceof RationaleDialogFragmentCompat) {
Log.d(TAG, "Found existing fragment, not showing rationale.");
return;
}
RationaleDialogFragmentCompat
.newInstance(rationale, positiveButton, negativeButton, theme, requestCode, perms)
.showAllowingStateLoss(fm, RationaleDialogFragmentCompat.TAG);
}
复制代码
RationaleDialogFragmentCompat继承自DialogFragment
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Rationale dialog should not be cancelable
setCancelable(false);
// Get config from arguments, create click listener
RationaleDialogConfig config = new RationaleDialogConfig(getArguments());
RationaleDialogClickListener clickListener =
new RationaleDialogClickListener(this, config, mPermissionCallbacks, mRationaleCallbacks);
// Create an AlertDialog
return config.createSupportDialog(getContext(), clickListener);
}
复制代码
RationaleDialogConfig:
AlertDialog createSupportDialog(Context context, Dialog.OnClickListener listener) {
AlertDialog.Builder builder;
if (theme > 0) {
builder = new AlertDialog.Builder(context, theme);
} else {
builder = new AlertDialog.Builder(context);
}
return builder
.setCancelable(false)
.setPositiveButton(positiveButton, listener)
.setNegativeButton(negativeButton, listener)
.setMessage(rationaleMsg)
.create();
}
复制代码
从上面看是可以把源码下载一份替换默认的AlertDialog后打包使用的,这个就不多说了。这里采用了另外一个方案:可以hook替换PermissionRequest的mHelper
private final PermissionHelper mHelper;
复制代码
更改mHelper的showRequestPermissionRationale方法来弹出自己的Dialog,先定义一个代理类:
public class PermissionsHelperProxy<T>(
private val permissionHelper: BaseSupportPermissionsHelper<T>
) : BaseSupportPermissionsHelper<T>(permissionHelper.host!!) {
override fun directRequestPermissions(requestCode: Int, vararg perms: String?) {
permissionHelper.directRequestPermissions(requestCode, *perms)
}
override fun shouldShowRequestPermissionRationale(perm: String): Boolean {
return permissionHelper.shouldShowRequestPermissionRationale(perm)
}
override fun getContext(): Context {
return permissionHelper.context
}
override fun getSupportFragmentManager(): FragmentManager {
return permissionHelper.supportFragmentManager
}
override fun showRequestPermissionRationale(
rationale: String,
positiveButton: String,
negativeButton: String,
@StyleRes theme: Int,
requestCode: Int,
vararg perms: String
) {
CommonDialog.Builder(context).build().show()
}
复制代码
在请求权限时替换:
private fun requestPermission(vararg perms: String) {
val request = PermissionRequest.Builder(this, REQUEST_CODE_PERMISSIONS, *perms)
.setRationale("This app may not work correctly without the requested permissions.")
.setPositiveButtonText("确定")
.setNegativeButtonText("取消")
.build()
try {
val clazz = request.javaClass
val field = clazz.getDeclaredField("mHelper")
field.isAccessible = true
val permissionHelper =
field.get(request) as BaseSupportPermissionsHelper<AppCompatActivity?>
field.set(request, PermissionsHelperProxy(permissionHelper))
} catch (e: Exception) {
}
EasyPermissions.requestPermissions(request)
}
复制代码
成功:
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END