Android官方资料地址:
运行时权限申请
https://developer.android.com/training/permissions/requesting.html
权限列表
https://developer.android.com/guide/topics/security/permissions.html#defining
###1、校验权限的回调接口
自定义的回调接口,后面会用到
public interface CheckPermissionListener {
/**
* 授权成功
* @param permissionName 具体取值参照 Manifest.permission.XXX_XX
*/
void onPermissionGranted(String permissionName);
/**
* 授权失败
* @param permissionName 具体取值参照 Manifest.permission.XXX_XX
*/
void onPermissionDenied(String permissionName);
}
###2、从谷歌的官方文档可以看到,权限申请被多次拒绝之后(没有勾选不再询问),系统是可以给出权限申请的申请说明,即为什么要使用这个权限。
2.1、ActivityCompat.shouldShowRequestPermissionRationale(this, permissionName)
a.返回True。权限申请被多次拒绝之后(没有勾选不再询问)
b.返回False。权限申请被多次拒绝之后(勾选不再询问);用户已经同意了权限申请。
2.2、ContextCompat.checkSelfPermission(this,permissionName)
权限检查。返回-1(PackageManager.PERMISSION_DENIED)和0(PackageManager.PERMISSION_GRANTED)
2.3、权限申请对话框
ActivityCompat.requestPermissions(this, new String[] { permissionName },REQUEST_CODE_PERMISSIONS_REQUEST);
权限申请对话框,第二个参数标示申请的权限列表,第三个则是该申请的请求码(REQUEST_CODE,联想下就会知道会有结果回调)。
/**
* 申请权限的回调
*
* @param requestCode
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[],
int[] grantResults) {
}
###3、为了给调用提供及时的结果通知。我这边使用回调的方式,使调用者被动的接受结果。
/**
* 权限申请说明,即为什么要申请此权限的权限说明集合
* Key 权限名
* Value 权限申请说明
*/
private static HashMap permissionExplanationMap = new HashMap<>();
//初始化权限申请说明的集合
static {
//暂无
}
/**
* 权限申请回调处理集合
* Key 权限名
* Value 权限申请回调处理接口
*/
private static HashMap permissionCallBackMap = new HashMap<>();
###4、最终整理了两个方法
/**
* 校验权限是否授予
* @param permissionName 具体取值参照 Manifest.permission.XXX_XX
* @param checkPermissionListener 授权结果的回调
*/
public void checkPermission(String permissionName,
CheckPermissionListener checkPermissionListener) {
if (TextUtils.isEmpty(permissionName)) {
if (checkPermissionListener != null) {
checkPermissionListener.onPermissionDenied(permissionName);
}
return;
}
//添加回调
if (permissionCallBackMap.containsKey(permissionName)) {
permissionCallBackMap.remove(permissionName);
}
permissionCallBackMap.put(permissionName, checkPermissionListener);
if (ContextCompat.checkSelfPermission(this,
permissionName) != PackageManager.PERMISSION_GRANTED) {
if (checkPermissionListener != null) {
checkPermissionListener.onPermissionDenied(permissionName);
}
} else {
if (checkPermissionListener != null) {
checkPermissionListener.onPermissionGranted(permissionName);
}
}
}
/**
* 校验(并申请)权限
*
* @param permissionName 具体取值参照 Manifest.permission.XXX_XX
* @param checkPermissionListener 授权结果的回调
*/
public void checkAndRequestPermission(String permissionName,
CheckPermissionListener checkPermissionListener) {
if (TextUtils.isEmpty(permissionName)) {
LogUtil.d("权限名称为空,授权检查失败");
if (checkPermissionListener != null) {
checkPermissionListener.onPermissionDenied(permissionName);
}
return;
}
//添加回调
if (permissionCallBackMap.containsKey(permissionName)) {
permissionCallBackMap.remove(permissionName);
}
permissionCallBackMap.put(permissionName, checkPermissionListener);
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
permissionName) != PackageManager.PERMISSION_GRANTED) {
LogUtil.d("授权检查(" + permissionName + "),尚未授权");
// 是否需要展示权限申请说明,即为什么要申请此权限
if (ActivityCompat.shouldShowRequestPermissionRationale(this, permissionName)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
if (permissionExplanationMap.containsKey(permissionName)) {
toast(permissionExplanationMap.get(permissionName) + "");
}
LogUtil.d("授权检查失败(" + permissionName + "),给出权限申请说明");
if (checkPermissionListener != null) {
checkPermissionListener.onPermissionDenied(permissionName);
}
} else {
LogUtil.d("授权检查(" + permissionName + "),发起授权申请");
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this, new String[] { permissionName },
REQUEST_CODE_PERMISSIONS_REQUEST);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
} else {
LogUtil.d("授权检查(" + permissionName + "),已授权。");
if (checkPermissionListener != null) {
checkPermissionListener.onPermissionGranted(permissionName);
}
}
}
###5、最终代码如下
/**
* 权限申请回调处理集合
* Key 权限名
* Value 权限申请回调处理接口
*/
private static HashMap permissionCallBackMap = new HashMap<>();
/**
* 权限申请说明,即为什么要申请此权限的权限说明集合
* Key 权限名
* Value 权限申请说明
*/
private static HashMap permissionExplanationMap = new HashMap<>();
//初始化权限申请说明的集合
static {
//暂无
}
//权限申请的请求代码
private static final int REQUEST_CODE_PERMISSIONS_REQUEST = 10;
/**
* 校验权限是否授予
* @param permissionName 具体取值参照 Manifest.permission.XXX_XX
* @param checkPermissionListener 授权结果的回调
*/
public void checkPermission(String permissionName,
CheckPermissionListener checkPermissionListener) {
if (TextUtils.isEmpty(permissionName)) {
if (checkPermissionListener != null) {
checkPermissionListener.onPermissionDenied(permissionName);
}
return;
}
//添加回调
if (permissionCallBackMap.containsKey(permissionName)) {
permissionCallBackMap.remove(permissionName);
}
permissionCallBackMap.put(permissionName, checkPermissionListener);
if (ContextCompat.checkSelfPermission(this,
permissionName) != PackageManager.PERMISSION_GRANTED) {
if (checkPermissionListener != null) {
checkPermissionListener.onPermissionDenied(permissionName);
}
} else {
if (checkPermissionListener != null) {
checkPermissionListener.onPermissionGranted(permissionName);
}
}
}
/**
* 校验(并申请)权限
*
* @param permissionName 具体取值参照 Manifest.permission.XXX_XX
* @param checkPermissionListener 授权结果的回调
*/
public void checkAndRequestPermission(String permissionName,
CheckPermissionListener checkPermissionListener) {
if (TextUtils.isEmpty(permissionName)) {
LogUtil.d("权限名称为空,授权检查失败");
if (checkPermissionListener != null) {
checkPermissionListener.onPermissionDenied(permissionName);
}
return;
}
//添加回调
if (permissionCallBackMap.containsKey(permissionName)) {
permissionCallBackMap.remove(permissionName);
}
permissionCallBackMap.put(permissionName, checkPermissionListener);
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
permissionName) != PackageManager.PERMISSION_GRANTED) {
LogUtil.d("授权检查(" + permissionName + "),尚未授权");
// 是否需要展示权限申请说明,即为什么要申请此权限
if (ActivityCompat.shouldShowRequestPermissionRationale(this, permissionName)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
if (permissionExplanationMap.containsKey(permissionName)) {
toast(permissionExplanationMap.get(permissionName) + "");
}
LogUtil.d("授权检查失败(" + permissionName + "),给出权限申请说明");
if (checkPermissionListener != null) {
checkPermissionListener.onPermissionDenied(permissionName);
}
} else {
LogUtil.d("授权检查(" + permissionName + "),发起授权申请");
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this, new String[] { permissionName },
REQUEST_CODE_PERMISSIONS_REQUEST);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
} else {
LogUtil.d("授权检查(" + permissionName + "),已授权。");
if (checkPermissionListener != null) {
checkPermissionListener.onPermissionGranted(permissionName);
}
}
}
/**
* 申请权限的回调
*
* @param requestCode
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[],
int[] grantResults) {
String permission = "";
if (permissions != null) {
permission = permissions[0];
}
//如果请求的权限为空,则不再继续处理
if (TextUtils.isEmpty(permission)) {
return;
}
LogUtil.d("授权(" + Arrays.toString(permissions) + ")申请结果(0=GRANTED;-1=DENIED):"
+ Arrays.toString(grantResults));
//获得权限的回调
CheckPermissionListener checkPermissionListener = permissionCallBackMap.get(permission);
switch (requestCode) {
case REQUEST_CODE_PERMISSIONS_REQUEST: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
if (checkPermissionListener != null) {
//已授权
checkPermissionListener.onPermissionGranted(permission);
}
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
if (checkPermissionListener != null) {
//拒绝
checkPermissionListener.onPermissionDenied(permission);
}
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}