随着android6.0的普及,大部分公司已经提出产品要兼容6.0系统的需求了.但是兼容了6.0系统,各种各样的问题也就接踵而至,相信各位没少为这些问题头疼.今天说一下6.0权限加固的解决办法.
android6.0系统权限加固了,像一些比较敏感的权限在app中不能像以前系统一样直接在清单文件中获取了.需要手动想用户请求,给予授权.如果没有请求,你就会发现原先能获得的一些文件地址,你拿不到了,抛出了NotFoundException,这是因为你项目的读写权限在6.0系统中没有拿到,即使你在AndroidManifest.xml文件里填写了相关权限,也是没有用的.你必须得手动请求,并且用户同意授权才行.
代码如下
/**
* shouldShowRequestPermissionRationale的返回值全部为 true时flag才为true
*/
private static boolean flag = true;
/**
* 权限状态监听接口
*/
public interface PermissionCallBack extends ActivityCompat.OnRequestPermissionsResultCallback {
/**
* 权限被授予
*/
void permissionGranted(int requestCode, List<String> perms);
/**
* 权限被拒绝
*/
void permissionDenied(int requestCode, List<String> perms);
}
flag表示是否请求成功,PermissionCallBack 请求回调.
然后就是分情况请求,比如在activity里请求权限,代码如下
/**
* 请求方法-Activity中
*
* 在onRequestPermissionsResult方法中实现PermissionUtil.requestPermisson方法
*
* @param permission 需要请求的权限
* @param permissionDes 需要请求的权限中文描述
* @param PERMS_REQUEST_CODE onRequestPermissionsResult中的请求码
* @param context 环境变量
*/
@TargetApi(Build.VERSION_CODES.M)
public static void requestPermisson(@NonNull Context context, int PERMS_REQUEST_CODE,
@NonNull String permissionDes,@NonNull String... permission) {
requestPermisson(context,null,PERMS_REQUEST_CODE,permissionDes,permission);
}
requestPermisson代码如下
/**
* 请求方法-Fragment中
*
* 在onRequestPermissionsResult方法中实现PermissionUtil.requestPermisson方法
*
* @param permission 需要请求的权限
* @param permissionDes 需要请求的权限中文描述
* @param PERMS_REQUEST_CODE onRequestPermissionsResult中的请求码
* @param context 环境变量
* @param fragment 传递fragment.this
*/
@TargetApi(Build.VERSION_CODES.M)
public static void requestPermisson(@NonNull Context context, @NonNull Fragment fragment, int PERMS_REQUEST_CODE,
@NonNull String permissionDes, @NonNull String... permission) {
final Activity mActivity = (Activity) context;
Object obj = null;
if (null != fragment) obj = fragment;
else obj = mActivity;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
String[] perTempPermissionDenied = checkPermissionGranted(mActivity,fragment, permission);
if (perTempPermissionDenied.length > 0) {
String[] perTempRequireToInfo = processPermissionNative(perTempPermissionDenied,1);
if (flag) {
if (perTempPermissionDenied.length == perTempRequireToInfo.length){//权限拒绝并且都没有提示
if (null != fragment){
fragment.requestPermissions(perTempRequireToInfo, PERMS_REQUEST_CODE);
}else {
mActivity.requestPermissions(perTempRequireToInfo, PERMS_REQUEST_CODE);
}
}else {//拒绝过部分没有提示
if (obj instanceof PermissionCallBack)
((PermissionCallBack) obj).permissionDenied(PERMS_REQUEST_CODE, Arrays.asList(permission));
ToastUtil.show(context, "您已经拒绝提示申请(" + permissionDes + ")权限,暂时无法使用此功能,请手动打开");
}
} else {
flag = true;
if (obj instanceof PermissionCallBack)
((PermissionCallBack) obj).permissionDenied(PERMS_REQUEST_CODE, Arrays.asList(permission));
ToastUtil.show(context, "您已经拒绝提示申请(" + permissionDes + ")权限,暂时无法使用此功能,请手动打开");
}
} else {
processPermissionNative(permission,2);
if (obj instanceof PermissionCallBack)
((PermissionCallBack) obj).permissionGranted(PERMS_REQUEST_CODE, Arrays.asList(permission));
}
} else {
processPermissionNative(permission,2);
if (obj instanceof PermissionCallBack)
((PermissionCallBack) obj).permissionGranted(PERMS_REQUEST_CODE, Arrays.asList(permission));
}
}
另外需要将配置过的权限过滤,以及其他处理
/**
* 配置本地已经配置过的权限过滤
* @param perTemp
* @param processType 1、保存;2、清除
* @return
*/
private static String[] processPermissionNative(String[] perTemp, int processType) {
String nativeProcess = PublicFunction.getPrefString(“permission_native_process”, “”);
ArrayList list = new ArrayList<>();
for (String permission:perTemp){
if (processType == 1){
if (!nativeProcess.contains(permission)) {
list.add(permission);
nativeProcess = nativeProcess + “#” + permission;
}
}else if (processType == 2){
nativeProcess = nativeProcess.replace(“#” +permission,”“).trim();
}
}
PublicFunction.setPrefString(“permission_native_process”, nativeProcess);
return list.toArray(new String[list.size()]);
}
/**
* 提取所有没有被授予的权限,如果有权限被设置为不再提示则设置flag为false
*
* @param mActivity
* @param permissions
* @return 没有被授予的权限
*/
@RequiresApi(api = Build.VERSION_CODES.M)
private static String[] checkPermissionGranted(Activity mActivity,Fragment fragment, @NonNull String[] permissions) {
ArrayList list = new ArrayList<>();
if (permissions.length > 0) {
for (String permission : permissions) {
if (!TextUtils.isEmpty(permission.trim())
&& (mActivity.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED)) {
list.add(permission);
if (null != fragment) {
if (!fragment.shouldShowRequestPermissionRationale(permission))
flag = false;
}else {
if (!mActivity.shouldShowRequestPermissionRationale(permission))
flag = false;
}
}
}
}
return (String[]) list.toArray(new String[list.size()]);
}
/**
* 对权限选择之后的onRequestPermissionsResult进行处理
*
* @param permsRequestCode
* @param permissions
* @param grantResults
* @param context
* @param activity 传递this
*/
@TargetApi(Build.VERSION_CODES.M)
public static void onRequestPermissionsResult(int permsRequestCode,String[] permissions, int[] grantResults
, @NonNull final Context context, @NonNull Activity activity) {
int grantResultsCount = 0;
for (int grantResult : grantResults) {
if (PackageManager.PERMISSION_GRANTED == grantResult) {
grantResultsCount++;
} else break;
}
if (grantResultsCount == grantResults.length) {
((PermissionCallBack) activity).permissionGranted(permsRequestCode, Arrays.asList(permissions));
} else {
((PermissionCallBack) activity).permissionDenied(permsRequestCode, Arrays.asList(permissions));
if (grantResults.length == 1) ToastUtil.show(context, "权限被拒绝,不能使用此功能");
else ToastUtil.show(context, "全部或部分权限被拒绝,不能使用此功能");
}
}
/**
* 对权限选择之后的onRequestPermissionsResult进行处理
*
* @param permsRequestCode
* @param permissions
* @param grantResults
* @param context
* @param fragment 传递Fragment.this
*/
@TargetApi(Build.VERSION_CODES.M)
public static void onRequestPermissionsResult(int permsRequestCode,String[] permissions, int[] grantResults
, @NonNull final Context context, @NonNull Fragment fragment) {
int grantResultsCount = 0;
for (int grantResult : grantResults) {
if (PackageManager.PERMISSION_GRANTED == grantResult) {
grantResultsCount++;
} else break;
}
if (grantResultsCount == grantResults.length) {
((PermissionCallBack) fragment).permissionGranted(permsRequestCode, Arrays.asList(permissions));
} else {
((PermissionCallBack) fragment).permissionDenied(permsRequestCode, Arrays.asList(permissions));
if (grantResults.length == 1) ToastUtil.show(context, "权限被拒绝,不能使用此功能");
else ToastUtil.show(context, "全部或部分权限被拒绝,不能使用此功能");
}
}
调用的时候直接调用requestPermisson方法就可以.