这个工具类优点:可以在能拿到Context的任意地方去申请权限,不用依赖activity的onRequestPermissionsResult回调方法获取返回结果。
使用的代码看下面:
//可以一次申请一个或多个权限,而且只需下面这一段代码就行了,
//不需要在其他地方额外再加代码,很简单有木有
AppPermissionUtil.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO,Manifest.permission.WRITE_EXTERNAL_STORAGE}, new AppPermissionUtil.OnPermissionListener() {
@Override
public void onPermissionGranted() {
//授权
}
@Override
public void onPermissionDenied() {
//没有授权,或者有一个权限没有授权
}
});
下面是工具类代码,一共两个类
import android.content.Context;
import android.os.Build;
/**
* 新版动态权限申请类
* 说明:不用依赖activity接收回调,可以再任意地方请求权限
* Created by yangqin on 2018/5/28.
*/
public class AppPermissionUtil {
/**
* 去请求所有权限
* @param context
* @param permissions 需要请求的权限列表
* @param listener 请求权限回调
*/
public static void requestPermissions(Context context, String[] permissions, OnPermissionListener listener) {
if(context==null||listener==null){
throw new NullPointerException("context参数为空,或者listener参数为空");
}
if (Build.VERSION.SDK_INT <= 22) {
//SDK小于22之前的版本之前发返回权限允许
listener.onPermissionGranted();
} else {
//打开一个一像素的activity去请求权限,并回调返回结果
RequestPermissionsHelpActivity.start(context,permissions,listener);
}
}
public interface OnPermissionListener {
void onPermissionGranted();//授权
void onPermissionDenied();//拒绝
}
}
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.Window;
import android.view.WindowManager;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* 动态请求权限帮助activity,与AppPermissionUtil联用。
* 注:这个不是我们app的页面,所有不要轻易改动。
*/
public class RequestPermissionsHelpActivity extends AppCompatActivity {
private int requestCode;
//设计两个OnPermissionListener的原因是,有效缓解并发请求权限时,OnPermissionListener公用一个会引发回调错乱或没法回调的问题
private static AppPermissionUtil.OnPermissionListener transferOnPermissionListener;//这个静态变量充当一个传递者的角色,传递给mOnPermissionListener变量后,就释放引用了
private AppPermissionUtil.OnPermissionListener mOnPermissionListener;//这个才是我们每次权限请求使用的回调监听
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//1像素的activity
Window window = getWindow();
window.setGravity(Gravity.LEFT | Gravity.TOP);
WindowManager.LayoutParams params = window.getAttributes();
params.x = 0;
params.y = 0;
params.height = 1;
params.width = 1;
window.setAttributes(params);
//获取界面传过来的值
getIntentData();
}
private void getIntentData(){
//获取传递过来回调监听
mOnPermissionListener=transferOnPermissionListener;
transferOnPermissionListener=null;
//传过来的需要申请的权限
String[] permissions=getIntent().getStringArrayExtra("permissions");
if(permissions!=null&&permissions.length>0){
requestPermissions(permissions);
}else {
//手动报错提示
throw new NullPointerException("申请的权限列表不能为空!");
}
}
/**
* 去申请所有权限
* @param permissions
*/
@TargetApi(Build.VERSION_CODES.M)
private void requestPermissions(String[] permissions){
Random random=new Random();
requestCode=random.nextInt(1000);
List<String> deniedPermissions = getDeniedPermissions(permissions);
if (deniedPermissions.size() > 0) {
//没有授权过,去申请一下
requestPermissions(deniedPermissions.toArray(new String[deniedPermissions.size()]), requestCode);
} else {
//都已经授权过了
if(mOnPermissionListener!=null)
mOnPermissionListener.onPermissionGranted();
if(!isFinishing()) {
finish();
}
}
}
/**
* 请求权限结果
*/
public void requestPermissionsResult(int requestCode, int[] grantResults) {
if (requestCode != -1 && requestCode == requestCode) {
if (verifyPermissions(grantResults)) {
//都授权了
if(mOnPermissionListener!=null)
mOnPermissionListener.onPermissionGranted();
finish();
} else {
//有一个未授权或者多个未授权
if(mOnPermissionListener!=null)
mOnPermissionListener.onPermissionDenied();
finish();
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//申请权限结果返回
requestPermissionsResult(requestCode,grantResults);
}
/**
* 获取请求权限中需要授权的权限,有的可能已经授权过了
*/
private List<String> getDeniedPermissions(String[] permissions) {
List<String> deniedPermissions = new ArrayList<>();
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_DENIED) {
deniedPermissions.add(permission);
}
}
return deniedPermissions;
}
/**
* 验证所有权限是否都已经授权
*/
private static boolean verifyPermissions(int[] grantResults) {
for (int grantResult : grantResults) {
if (grantResult != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
@Override
protected void onDestroy() {
super.onDestroy();
mOnPermissionListener=null;
}
/**
* 启动activity,并带些必要参数过来
* @param context
* @param permissions 申请权限列表
* @param listener 结果回调
*/
public static void start(Context context, String[] permissions, AppPermissionUtil.OnPermissionListener listener){
Intent intent = new Intent(context, RequestPermissionsHelpActivity.class);
intent.putExtra("permissions",permissions);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
transferOnPermissionListener=listener;
}
}
manifest也需要配置一下:
<activity
android:name=".RequestPermissionsHelpActivity"
android:configChanges="keyboardHidden|orientation|screenSize|navigation|keyboard"
android:theme="@style/transparencyActivityStyle" />
这个是activity的透明样式:
<style name="transparencyActivityStyle" parent="Theme.AppCompat">
<item name="android:windowBackground">@color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoDisplay">false</item>
<item name="android:windowDisablePreview">true</item>
</style>
最后就是一点透明颜色:
<color name="transparent">#00000000</color>
作者独白:建一栋高楼,高楼的结构没有研究清楚,却一直在研究如何节省时间砌好一面墙。 哈哈哈,跑偏了 , 捂脸。。。。