提取RxPermissions核心思想, 搭建自己的权限请求框架

2018-03-01 11:19:35来源:https://www.jianshu.com/p/66d386684d0f作者:FrankChoo人点击

分享


封装目的

有的项目中不需要使用 RxJava 异步事件流相关, 只需要一个好用灵活的权限请求框架, 而 RxPermissions 其内部使用的方式就比较精妙, 让我产生了把它内部精华部分提取出来的动力


使用方式

搭配上 Kotlin 的语法糖, 可以看到写起来非常的干练和舒服


 PermissionsManager.getManager(this)
.request(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
.execute {
if (it) {
Toast.makeText(this, "Granted", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "Denial", Toast.LENGTH_SHORT).show()
}
}

搭建过程
依赖:
Fragment.requestPermissions 方法, 可以用来发起对权限的请求
Fragment.onRequestPermissionsResult 方法, 可以监听权限请求的回调

思路:
发起权限请求的时候, 根据传入的 context, 找到对应的 Activity
先判断有没有添加过
若未添加过: 向这个 Activity 中添加一个我们封装好的用于权限请求的 Fragment
已经添加过: 通过 Activity.getFragmentManager().findFragmentByTag(TAG) 获取之前添加过的实例

通过这个 Fragment 来发起权限请求
请求失败后, 弹出 Dialog, 给用户跳转到设置界面去开启权限的选项

实现代码
/**
* Created by FrankChoo on 2018/1/5.
* Email: frankchoochina@gmail.com
* Version:1.1
* Description: 权限请求管理类, 实现思路来自 RxPermissions
*/
public class PermissionsManager {
public static final String TAG = "PermissionsManager";
private PermissionsFragment mPermissionsFragment;
private String[] mPermissions;
public static PermissionsManager getManager(Context context) {
if (context instanceof Activity) {
Activity activity = (Activity) context;
return new PermissionsManager(activity);
} else {
throw new IllegalArgumentException("PermissionsManager.getManager/Context can not cast to Activity");
}
}
private PermissionsManager(Activity activity) {
mPermissionsFragment = getPermissionsFragment(activity);
Log.e("TAG", mPermissionsFragment.toString());
}
/**
* 添加需要请求的权限
*/
public PermissionsManager request(final String... permissions) {
ensure(permissions);
mPermissions = permissions;
return this;
}
/**
* 执行权限请求
*/
public void execute(PermissionsCallback permissionsCallback) {
if (permissionsCallback == null) {
throw new IllegalArgumentException("PermissionsManager.execute/PermissionsCallback must not be null");
}
requestImplementation(mPermissions, permissionsCallback);
}
/**
* 判断权限是否被授权
*/
public boolean isGranted(String permission) {
return !isMarshmallow() || mPermissionsFragment.isGranted(permission);
}
/**
* 判断权限是否被撤回
* <p>
* Always false if SDK &lt; 23.
*/
@SuppressWarnings("WeakerAccess")
public boolean isRevoked(String permission) {
return isMarshmallow() && mPermissionsFragment.isRevoked(permission);
}
/**
* 获取 PermissionsFragment
*/
private PermissionsFragment getPermissionsFragment(Activity activity) {
PermissionsFragment permissionsFragment = findPermissionsFragment(activity);
if (permissionsFragment == null) {
permissionsFragment = PermissionsFragment.getInstance();
FragmentManager fragmentManager = activity.getFragmentManager();
fragmentManager.beginTransaction().add(permissionsFragment, TAG).commitAllowingStateLoss();
fragmentManager.executePendingTransactions();
}
return permissionsFragment;
}
/**
* 在 Activity 中通过 TAG 去寻找我们添加的 Fragment
*/
private PermissionsFragment findPermissionsFragment(Activity activity) {
return (PermissionsFragment) activity.getFragmentManager().findFragmentByTag(TAG);
}

/**
* 验证发起请求的权限是否有效
*/
private void ensure(String[] permissions) {
if (permissions == null || permissions.length == 0) {
throw new IllegalArgumentException("PermissionsManager.request/requestEach requires at least one input permission");
}
}
/**
* 执行权限请求
*
* @param permissions
* @param callback
*/
private void requestImplementation(String[] permissions, PermissionsCallback callback) {
List<String> unrequestedPermissions = new ArrayList<>();
for (String permission : permissions) {
mPermissionsFragment.log("Requesting permission " + permission);
if (isGranted(permission)) {
// Already granted, or not Android M
// Return a granted Permission object.
continue;
}
if (isRevoked(permission)) {
// Revoked by a policy, return a denied Permission object.
continue;
}
unrequestedPermissions.add(permission);
}
if (!unrequestedPermissions.isEmpty()) {
// 细节, toArray的时候指定了数组的长度
String[] unrequestedPermissionsArray = unrequestedPermissions.toArray(new String[unrequestedPermissions.size()]);
mPermissionsFragment.requestPermissions(unrequestedPermissionsArray, callback);
} else {
callback.onResult(true);
}
}
private boolean isMarshmallow() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}
}

/**
* Created by FrankChoo on 2018/1/5.
* Email: frankchoochina@gmail.com
* Version:1.1
* Description: 执行权限请求的 Fragment
*/
public class PermissionsFragment extends Fragment {
private static final int PERMISSIONS_REQUEST_CODE = 42;
private PermissionsCallback mCallback;
public static PermissionsFragment getInstance() {
return new PermissionsFragment();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@TargetApi(Build.VERSION_CODES.M)
void requestPermissions(@NonNull String[] permissions, PermissionsCallback callback) {
mCallback = callback;
requestPermissions(permissions, PERMISSIONS_REQUEST_CODE);
}
@Override
@TargetApi(Build.VERSION_CODES.M)
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode != PERMISSIONS_REQUEST_CODE) return;
boolean isAllGranted = true;
for (int i = 0, size = permissions.length; i < size; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
log("onRequestPermissionsResult: " + permissions[i] + " is Granted");
} else {
log("onRequestPermissionsResult: " + permissions[i] + " is Denied");
isAllGranted = false;
}
}
if (isAllGranted) {
mCallback.onResult(true);
} else {
showPermissionDeniedDialog();
}
}
@TargetApi(Build.VERSION_CODES.M)
boolean isGranted(String permission) {
return getActivity().checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
}
@TargetApi(Build.VERSION_CODES.M)
boolean isRevoked(String permission) {
return getActivity().getPackageManager().isPermissionRevokedByPolicy(permission, getActivity().getPackageName());
}
@TargetApi(Build.VERSION_CODES.M)
private void showPermissionDeniedDialog() {
//启动当前App的系统设置界面
AlertDialog dialog = new AlertDialog.Builder(getContext())
.setTitle("帮助")
.setMessage("当前应用缺少必要权限")
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mCallback.onResult(false);
dialog.dismiss();
}
})
.setPositiveButton("设置", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getContext(), "设置成功后请重新请求该操作", Toast.LENGTH_SHORT).show();
//启动当前App的系统设置界面
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getContext().getPackageName()));
startActivity(intent);
}
}).create();
dialog.show();
}
void log(String message) {
Log.d(PermissionsManager.TAG, message);
}
}

/**
* Created by FrankChoo on 2018/1/5.
* Email: frankchoochina@gmail.com
* Description: 权限请求回调
*/
public interface PermissionsCallback {
void onResult(boolean granted);
}







最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台