关于Android6.0运行时权限的总结(干货)。
三种对运行时权限的封装:
1.用一个透明的Activity来实现
2.用Fragment来实现 (在Fragment中实现的)
https://github.com/tbruyelle/RxPermissions
3.在BaseActivity来实现(主要介绍)
步骤:
1.重写BaseActivity
2.需要的Activity调用
基类:
public class BaseActivity extends AppCompatActivity {
private PermissionListener mPermissionListener;
//运行时权限的请求方法的封装
public void requestRuntimePermission(String[] permissions,PermissionListener permissionListener) {
mPermissionListener = permissionListener;
List<String> permissionList = new ArrayList<>();
//判断版本是否大于等于6.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//循环遍历权限数组
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
//若果没有同意就添加到集合中
permissionList.add(permission);
}
}
//判断集合是否为空
if (!permissionList.isEmpty()) {
//不为空,就说明有权限没有同意,需要同意
ActivityCompat.requestPermissions(this, permissionList.toArray(new String[permissionList.size()]), 1);
} else {//都同意了
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 1:
if (grantResults.length>0) {//权限不为空
List<String> deniedPermissionList = new ArrayList<>();
//循环遍历整个权限回调数组吧不同意的添加到集合中去
for(int i= 0; i< grantResults.length;i++){
int grantResult = grantResults[i];
String permission = permissions[i];
if(grantResult != PackageManager.PERMISSION_GRANTED) {
deniedPermissionList.add(permission);
}
}
//如果集合为空,就走回调的同意方法
if(deniedPermissionList.isEmpty()){
// Permission Granted
mPermissionListener.granted();
}else{//如果集合不为空,就走回调的拒绝方法
// Permission denied
mPermissionListener.denied(deniedPermissionList);
}
}
break;
default:
break;
}
}
}
回调接口:
public interface PermissionListener {
void granted();
void denied(List<String> deniedList );
}
2.应用:
在MainActivity中用到权限申请,要继承BaseActivity
public class MainActivity extends BaseActivity
在用到的地方(例如点击某个按钮):代码:
case R.id.text_bt3:
//运行时权限
requestRuntimePermission(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.CAMERA}, new PermissionListener() {
@Override
public void granted() {
Toast.makeText(MainActivity.this, "所有权限都同意了", Toast.LENGTH_SHORT).show();
}
@Override
public void denied(List<String> deniedList) {
for(String denied:deniedList ){
Toast.makeText(MainActivity.this, denied+"权限被拒绝,请在设置中打开相关权限", Toast.LENGTH_SHORT).show();
}
}
});
break;
-------------------------------------------------------------------------------------------------------------------------------------------
以上封装只能在Activity中使用,为了扩展性再次优化封装(可以普通类使用)
修改步骤:
1.BaseActivity 中的方法requestRuntimePermission改成static静态的
2.由于静态后找不到上下文环境,所有新建一个Activity的管理类ActivityCollector类
3
1.BaseActivity中
代码如下:
public class BaseActivity extends AppCompatActivity {
private static PermissionListener mPermissionListener;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityCollector.addActivity(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);
}
//运行时权限的请求方法的封装
public static void requestRuntimePermission(String[] permissions,PermissionListener permissionListener) {
//获得栈顶Activity
Activity topActivity = ActivityCollector.getTopActivity();
if(topActivity == null){//栈顶为空直接返回
return;
}
mPermissionListener = permissionListener;
List<String> permissionList = new ArrayList<>();
//判断版本是否大于等于6.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//循环遍历权限数组
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission( topActivity , permission) != PackageManager.PERMISSION_GRANTED) {
//若果没有同意就添加到集合中
permissionList.add(permission);
}
}
//判断集合是否为空
if (!permissionList.isEmpty()) {
//不为空,就说明有权限没有同意,需要同意
ActivityCompat.requestPermissions( topActivity , permissionList.toArray(new String[permissionList.size()]), 1);
} else {//都同意了
}
}
}
2新建的ActivityCollector
public class ActivityCollector {
private static List<Activity> activityList = new ArrayList<>();
//添加
public static void addActivity(Activity activity) {
activityList.add(activity);
}
//删除
public static void removeActivity(Activity activity) {
activityList.remove(activity);
}
//获得栈顶Activity
public static Activity getTopActivity() {
if (activityList.isEmpty()) {
return null;
} else {
return activityList.get(activityList.size() - 1);
}
}
}
调用:
在一个一般的类中:
直接在类中调用就OK
BaseActivity. requestRuntimePermission(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.CAMERA}, new PermissionListener() {
@Override
public void granted() {
}
@Override
public void denied(List<String> deniedList) {
}
});
拓展;基于第一种的添加了小于6.0版本的判断:
行时权限的请求方法的封装
public class BaseActivity extends AppCompatActivity {
private PermissionListener mPermissionListener;
public void requestRuntimePermission(String[] permissions, PermissionListener permissionListener) {
mPermissionListener = permissionListener;
List<String> permissionList = new ArrayList<>();
//判断版本是否大于等于6.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//循环遍历权限数组
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
//若果没有同意就添加到集合中
permissionList.add(permission);
}
}
//判断集合是否为空
if (!permissionList.isEmpty()) {
//不为空,就说明有权限没有同意,需要同意
ActivityCompat.requestPermissions(this, permissionList.toArray(new String[permissionList.size()]), 1);
} else {//都同意了
mPermissionListener.granted();
}
} else {
List<String> deniedPermissionList = new ArrayList<>();
List p = Arrays.asList(permissions);
if (p.contains(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
try {
File file = new File(DirectoryBuilder.DIR_FILE + "temp");
file.createNewFile();
file.delete();
} catch (Exception e) {
deniedPermissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
}
if (p.contains(Manifest.permission.CAMERA)) {
try {
Camera camera = Camera.open(0);
camera.release();
} catch (Exception e) {
deniedPermissionList.add(Manifest.permission.CAMERA);
}
}
if (p.contains(Manifest.permission.RECORD_AUDIO)) {
VoiceChatRecorder voiceRecord = new VoiceChatRecorder();
boolean isHasPermission = voiceRecord.isHasPermission(this);
if (!isHasPermission) {
deniedPermissionList.add(Manifest.permission.RECORD_AUDIO);
}
}
if (deniedPermissionList.size() > 0) {
mPermissionListener.denied(deniedPermissionList);
} else {
mPermissionListener.granted();
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 1:
if (grantResults.length > 0) {//权限不为空
List<String> deniedPermissionList = new ArrayList<>();
//循环遍历整个权限回调数组吧不同意的添加到集合中去
for (int i = 0; i < grantResults.length; i++) {
int grantResult = grantResults[i];
String permission = permissions[i];
if (grantResult != PackageManager.PERMISSION_GRANTED) {
deniedPermissionList.add(permission);
}
}
//如果集合为空,就走回调的同意方法
if (deniedPermissionList.isEmpty()) {
// Permission Granted
mPermissionListener.granted();
} else {//如果集合不为空,就走回调的拒绝方法
// Permission denied
mPermissionListener.denied(deniedPermissionList);
}
}
break;
default:
break;
}
}
//权限回调接口
public interface PermissionListener {
void granted();
void denied(List<String> deniedList);
}
}
最后感谢郭神的视频:
视频地址: