目录
- 前言&演示
- 1、申请部分
- 1.1、Activiy申请
- 1.2、Fragment申请
- 2、回调部分
- 3、疑问
前言&演示
Android SDK23以后,使用权限需要显式申请。
最近的安卓项目反复使用到权限申请,于是把它写成了工具类。
演示:
权限申请实际演示
1、申请部分 1.1、Activiy申请 简单的说明:说明都在注释里面写了,我就挑重点说吧
权限数组:也可以用于申请单个权限(废话)
简单的调用:一般是把它写在一个检查权限的方法内部,要使用某项权限时,
调用这个方法去判断有没有权限。
public boolean checkPermission(){
//权限数组
String [] permissions={Manifest.permission.CALL_PHONE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};
//三个参数:
//permissions (权限数组)
//(上下文,只能这样调用:MainActivity.this)
//requestCode(请求码,标识你的申请)
return PermissionUtils.checkPermissions(permissions,0,MainActivity.this);
}
工具类:Activiy申请的方法:
public static boolean checkPermissions(String[] permissions, int requestCode,Activity activity) {
//判断版本
if (Build.VERSION.SDK_INT>=23){
int checkPermission;
//权限数组
@SuppressLint("InlinedApi")
List notGrantedList = new ArrayList<>();
for (String permission:permissions){
//检查是否已经授权
checkPermission = activity.checkSelfPermission(permission);
if (checkPermission!= PackageManager.PERMISSION_GRANTED){
//未授权则添加进未授权数组
notGrantedList.add(permission);
}
}
//未授权数组长度判空
if (notGrantedList.size()>0){
String[] notGrantedArray = new String[notGrantedList.size()];
notGrantedList.toArray(notGrantedArray);
//请求授权
activity.requestPermissions(notGrantedArray,requestCode);
return false;
}
}
return true;
}
1.2、Fragment申请
简单的调用:类似于Acticity申请
public boolean checkPermission(){
//权限数组
String [] permissions={Manifest.permission.CALL_PHONE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};
//三个参数:
//permissions (权限数组)
//(上下文,只能这样调用:Fragment.this)
//requestCode(请求码,标识你的申请)
return PermissionUtils.checkPermissions(permissions,0,Fragment.this);
}
工具类:fragment申请的方法:
public static boolean checkPermissions(String[] permissions, int requestCode,Fragment fragment) {
//判断版本
if (Build.VERSION.SDK_INT>=23){
int checkPermission;
//权限数组
@SuppressLint("InlinedApi")
List notGrantedList = new ArrayList<>();
for (String permission:permissions){
//检查是否已经授权
checkPermission = fragment.requireContext().checkSelfPermission(permission);
if (checkPermission!= PackageManager.PERMISSION_GRANTED){
//未授权则添加进未授权数组
notGrantedList.add(permission);
}
}
//未授权数组长度判空
if (notGrantedList.size()>0){
String[] notGrantedArray = new String[notGrantedList.size()];
notGrantedList.toArray(notGrantedArray);
//请求授权
fragment.requestPermissions(notGrantedArray,requestCode);
return false;
}
}
return true;
}
2、回调部分
简单的调用:
这个是通用的:fragment内部获取Activity上下文(activity activity = requireActivity();)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == 0){
String message ="缺少权限";
PermissionUtils.onPermissionResults(grantResults,MainActivity.this,message);
}
}
工具类:申请回调的方法:
public static void onPermissionResults(int[] grantResults,Activity activity,String message){
//输出请求结果的长度
System.out.println(grantResults.length);
//定义一个变量grantCount存储已经成功得到授权的权限
int grantCount = 0;
for(int grant : grantResults){
if(grant == PackageManager.PERMISSION_GRANTED){
grantCount ++;
}
}
//如果grantCount的与授权请求结果的数组长度大小不一致,
if(grantCount != grantResults.length){
// 权限获取失败 创建对话框提示用户
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
AlertDialog alertDialog = new AlertDialog.Builder(activity).setTitle("温馨提示")
//自定义提示消息
.setMessage(message)
.setPositiveButton("前往设置", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//跳转到应用设置界面获得授权
Intent intent = new Intent();
intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
intent.setData(Uri.fromParts("package",activity.getPackageName(), null));
activity.startActivity(intent);
}
})
.setNegativeButton("返回", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(activity, "取消", Toast.LENGTH_SHORT).show();
}
})
.create();
alertDialog.show();
}
});
}
}
3、疑问
为什么要有两种申请状况(Activity和Fragment)?
答:fragment和activity中内部都有各自申请权限的方法,虽然方法名相同,功能也一致。
但是,如果不是由对应的类型调用(Activity和Fragment),似乎就无法激发回调,
我自己测试的时候,结果就是这样。
感兴趣的话可以自己研究下。。
Activity的申请权限方法(源码)
public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
if (requestCode < 0) {
throw new IllegalArgumentException("requestCode should be >= 0");
}
if (mHasCurrentPermissionsRequest) {
Log.w(TAG, "Can request only one set of permissions at a time");
// Dispatch the callback with empty arrays which means a cancellation.
onRequestPermissionsResult(requestCode, new String[0], new int[0]);
return;
}
Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);
mHasCurrentPermissionsRequest = true;
}
Fragment的申请权限方法(源码)
public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
if (mHost == null) {
throw new IllegalStateException("Fragment " + this + " not attached to Activity");
}
mHost.onRequestPermissionsFromFragment(this, permissions, requestCode);
}



