转载请注明出处http://blog.youkuaiyun.com/u012532631/article/details/76996867
最近在项目中用到过动态权限控制,但是目前网上的以及Google开源的框架都无法满足我们的需求,所以决定写一个新的框架适合我们需要的这种情况。
目前网上的各种动态权限控制能满足的需求
一般的权限控制框架应用的地方都是在刚刚触发一个事件然后我们去请求相应的权限。
我们的需求是
请求相机权限,如果在Activity进行跳转前进行申请,那么即使通过,用户可能在相机使用界面退出到后台把权限关闭,这样在进来的时候就会导致异常并且无法提示。
最初的解决办法
既然用户可能到后台关闭相机权限,那我们就把判断放在onResume()中不就好了,这样就能在每次界面进来的时候都能判断。那么问题来了,我们向系统申请权限的时候系统会主动弹出一个Activity,当这个系统界面消失的时候,发送申请界面的onResume()又会触发一次。导致申请陷入一个死循环中。
解决办法
加一个标识位isActive = true,在用户选择禁止或者允许回调后isActive = false,在onStop()的时候isActive = true。原理差不多就这么多,当然还支持rationaleDialog显示。rationale是官方建议的用法,在用户在本应用拒绝申请的权限后再次申请的时候弹出一个Dialog提示用户该权限的说明,如果通过之后再去申请。
框架用法
这两部分就不细说了
<uses-permission android:name="android.permission.CAMERA"/>
compile 'com.xwy.spermission:spermission:1.0.0'
- module = 1(默认)
这种模式适用于只申请一次的情况,比如在进入页面的时候,在按钮点击的时候。上代码:
SPermission.with(MainActivity.this)
.setmRequestCode(1)
.setPermissions(new String[]{Manifest.permission.CAMERA})
.setmOnPermissionListener(new OnPermissionListener() {
@Override
public void onPermissionGranted() {
Toast.makeText(MainActivity.this, "相机打开", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onPermissionGranted:" + System.currentTimeMillis());
//startActivity(new Intent(MainActivity.this, CaptureActivity.class));
//init1();
//SPermission.sPermission.activeSPermission();
}
@Override
public void onPermissionDenied(String[] strings) {
Toast.makeText(MainActivity.this, "相机没有打开", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onPermissionDenied:" + System.currentTimeMillis());
//SPermission.sPermission.activeSPermission();
}
@Override
public void onPermissionDeniedAlways(String[] strings) {
Toast.makeText(MainActivity.this, "相机永久禁止", Toast.LENGTH_SHORT).show();
}
})
/*.setRationaleListener(new RationaleListener() {
@Override
public void onRationaleResult(String deniedPermission) {
Dialog dialog = new AlertDialog.Builder(MainActivity.this)
.setTitle("获取" + deniedPermission + "时权限被禁用")
.setMessage("请点击设置打开权限")
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setPositiveButton("去设置", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SPermission.getsPermission().requestPermissionsAgain();
}
})
.show();
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
SPermission.getsPermission().setDialogShow(false);
}
});
}
})*/
.requestPermissions();
然后重写回调方法
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
SPermission.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
[代码连接](https://github.com/AerialLadder/SPermission/blob/master/app/src/main/java/com/xwy/spermissions/MainActivity.java)
2. module = 2
SPermission.with(SecondActivity.this)
.setMOUDLE(2)
.setmRequestCode(1)
.setPermissions(new String[]{Manifest.permission.CAMERA})
.setmOnPermissionListener(new OnPermissionListener() {
@Override
public void onPermissionGranted() {
Toast.makeText(SecondActivity.this, "相机打开", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onPermissionGranted:" + System.currentTimeMillis());
//startActivity(new Intent(MainActivity.this, CaptureActivity.class));
//init1();
//SPermission.sPermission.activeSPermission();
}
@Override
public void onPermissionDenied(String[] strings) {
Toast.makeText(SecondActivity.this, "相机没有打开", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onPermissionDenied:" + System.currentTimeMillis());
//SPermission.sPermission.activeSPermission();
}
@Override
public void onPermissionDeniedAlways(String[] strings) {
Toast.makeText(SecondActivity.this, "相机永久禁止", Toast.LENGTH_SHORT).show();
}
})
.setRationaleListener(new RationaleListener() {
@Override
public void onRationaleResult(String deniedPermission) {
Dialog dialog = new AlertDialog.Builder(SecondActivity.this)
.setTitle("获取" + deniedPermission + "时权限被禁用")
.setMessage("请点击设置打开权限")
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setPositiveButton("去设置", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SPermission.getsPermission().requestPermissionsAgain();
}
})
.show();
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
SPermission.getsPermission().setDialogShow(false);
}
});
}
})
.requestPermissions();
然后重写回调方法
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
SPermission.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
重写onStop()
@Override
protected void onStop() {
super.onStop();
SPermission.getsPermission().activeSPermission();
}
如果要使用Rationale,那么里面的Dialog一样要有这几步,其他可以自己定义
.setRationaleListener(new RationaleListener() {
@Override
public void onRationaleResult(String deniedPermission) {
Dialog dialog = new AlertDialog.Builder(SecondActivity.this)
.setTitle("获取" + deniedPermission + "时权限被禁用")
.setMessage("请点击设置打开权限")
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setPositiveButton("去设置", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//在这里面去请求权限
SPermission.getsPermission().requestPermissionsAgain();
}
})
.show();
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
//响应后重置标识位
SPermission.getsPermission().setDialogShow(false);
}
});
}
})
.requestPermissions();
特别感谢
XPermissionUtils
AndPermission