首先,你要导入依赖:
implementation 'pub.devrel:easypermissions:1.1.2'
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
然后BaseActivity 是这样的:
public abstract class BaseActivity extends RxAppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(setLayout());
ButterKnife.bind(this);
doInOnCreate(savedInstanceState);
}
/**
* 将布局传进来
*
* @return R.layout.activity_test
*/
public abstract int setLayout();
/**
* 在activity 的onCreate()方法里面执行的代码块
*
* @param savedInstanceState bundle
*/
public abstract void doInOnCreate(Bundle savedInstanceState);
}
BasePermissionActivity 是这样的:
public abstract class BasePermissionActivity extends BaseActivity implements EasyPermissions.PermissionCallbacks {
private List<String> mGrantedList = new ArrayList<>();
private List<String> mDeniedList = new ArrayList<>();
/**
* 这个是你真实的需要申请几个权限。因为如果你一次性传了五个权限进来,那么这五个里面之前就有两个已经给了权限,所以
* 你只需要申请三个权限
*/
private int mRequestCode = 0, mOriginalList = 0;
private String mAlertMsg = "";
/**
* 先判断code 再 判断deniedList是否为空,为空代表你申请的权限给你了
*
* @param grantedList 已给予了的权限列表
* @param deniedList 已拒绝的权限列表
* @param requestCode code
*/
public abstract void requestResult(List<String> grantedList, List<String> deniedList, int requestCode);
/**
* 当申请权限的时候,直接调用这个方法就行。你可以无赖的每次将你所有的权限都扔进来,然后在requestResult()回调
* 里面进行处理,
*/
protected void startRequest(int requestCode, String alert, String... list) {
mRequestCode = requestCode;
mAlertMsg = alert;
mOriginalList = list.length;
mGrantedList.clear();
mDeniedList.clear();
requestPermission(list);
}
private void requestPermission(String... list) {
EasyPermissions.requestPermissions(this, mAlertMsg, mRequestCode, list);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
@Override
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
if (requestCode == mRequestCode) {
dealResult(false, perms);
}
}
@Override
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
if (requestCode == mRequestCode) {
dealResult(true, perms);
}
}
/**
* 其实这个方法最多走两次。假如你同时申请了多个权限,然后界面会弹框多次让用户去分别给权限。然后用户操作完之后
* 才会走拒绝和同意的回调。假如你有的权限同意了,有的权限拒绝了,那么就会先回调同意的方法onPermissionsGranted
* ,然后再走onPermissionsDenied,那么当前的这个方法dealResult 就会走两边的。
*
* @param granted true代表是同意
* @param perms 回调结果list
*/
private void dealResult(boolean granted, List<String> perms) {
for (String per : perms) {
if (granted) {
if (!mGrantedList.contains(per)) {
mGrantedList.add(per);
}
} else {
if (!mDeniedList.contains(per)) {
mDeniedList.add(per);
}
}
}
if (mDeniedList.size() + mGrantedList.size() == mOriginalList) {
requestResult(mGrantedList, mDeniedList, mRequestCode);
} else {
Logger.e("应该是同时申请了多个权限,并且有的权限同意了,有的拒绝了,还在继续加,不用着急,最后肯定会走总和那里的");
}
}
}
如果你在activity里面申请权限,用法如下:
public class TestActivity extends BasePermissionActivity {
@Override
public void requestResult(List<String> grantedList, List<String> deniedList, int requestCode) {
if (requestCode == 20) {
if (deniedList.isEmpty()) {
ToastUtils.showToast("给了权限");
} else {
ToastUtils.showToast("没给权限");
}
}
if (requestCode == 30) {
if (deniedList.isEmpty()) {
ToastUtils.showToast("给了权限");
} else {
ToastUtils.showToast("没给权限");
}
}
}
@Override
public int setLayout() {
return R.layout.activity_test;
}
@Override
public void doInOnCreate(Bundle savedInstanceState) {
}
public void test(View view) {
//申请单个权限测试
startRequest(20, "申请读写权限", Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
public void test2(View view) {
//申请多个权限测试
startRequest(30, "申请相机权限和定位权限", Manifest.permission.CAMERA
, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION);
}
}
TestActivity 的xml如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#ccc"
android:gravity="center"
android:onClick="test"
android:text="申请单个权限" />
<TextView
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="40dp"
android:background="#ccc"
android:gravity="center"
android:onClick="test2"
android:text="申请多个权限" />
</LinearLayout>
fragment里面的权限处理其实直接在BasePermissionActivity 的权限申请哪里这样处理,如下:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
// 获取到Activity下的Fragment
List<Fragment> fragments = activity.getSupportFragmentManager().getFragments();
if (fragments == null) {
return;
}
// 查找在Fragment中onRequestPermissionsResult方法并调用
for (Fragment fragment : fragments) {
if (fragment != null) {
// 这里就会调用我们Fragment中的onRequestPermissionsResult方法
fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}