您的位置:首页 > 移动开发 > Android开发

Android6.0权限适配

2016-10-04 23:04 423 查看
Android6.0引入了新的权限机制,早已有大神对此做过讲解,比如这篇文章:

http://blog.csdn.net/lmj623565791/article/details/50709663

本文对Android权限相关知识做一些其它补充。

一、 获取某个应用的权限清单(Manifest.xml中申请的权限)

private List<String> getAppRegistPermissions(){
List<String> permissionList = new ArrayList<>();
try {
PackageManager pm = getPackageManager();
PackageInfo pack = pm.getPackageInfo(getPackageName(),PackageManager.GET_PERMISSIONS);
String[] permissionStrings = pack.requestedPermissions;
permissionList = Arrays.asList(permissionStrings);
return permissionList;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return permissionList;
}

二、检查APP是否申请了某项权限

int granted = 0;
//1、android6.0及以上
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
granted = checkSelfPermission(permission);
}
//2、使用support包中的ContextCompat
granted = ContextCompat.checkSelfPermission(this, permission);

//3、通过PackageManager判断
PackageManager pm = getPackageManager();
granted=pm.checkPermission(permission, getPackageName());


三、适配Android6.0以上

1、在AndroidManifest文件中添加需要的权限。

2、检查权限

private boolean hasPermission(String... permissions) {
for (String permission : permissions) {
int granted = ContextCompat.checkSelfPermission(this, permission);
if(granted == PackageManager.PERMISSION_DENIED){
return false;
}
}
return true;
}


3、申请授权

private void requestPermissions(int reqCode, String... permissions) {
ActivityCompat.requestPermissions(this, permissions, reqCode);
}


4、处理权限申请回调

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
List<String> deniedPermissions = new ArrayList<>();
for(int i=0; i<grantResults.length; i++){
if(grantResults[i] != PackageManager.PERMISSION_GRANTED){
deniedPermissions.add(permissions[i]);
}
}

if(deniedPermissions.size() > 0){
//权限被拒绝
} else {
//权限申请成功
}
}


不过还有个API值得提一下:

// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS))
// 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.

}
     这个API主要用于给用户一个申请权限的解释,该方法只有在用户在上一次已经拒绝过你的这个权限申请。也就是说,用户已经拒绝一次了,你又弹个授权框,

你需要给用户一个解释,为什么要授权,则使用该方法。

那么将上述几个步骤结合到一起就是:

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {

// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {

// 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.

} else {

// No explanation needed, we can request the permission.

ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);

// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}

四、权限封装

从android6.0后可以看出,权限检查、权限申请完全一致,就权限回调处理不太一样,也就是说,如果我们要做封装,难点就在于完成权限申请成功和失败的处理。然而

权限成功和失败的处理和具体业务逻辑绑定的,我们没法预先知道具体方法,这时候反射就排上用场了。在Activity或Fragment中定义我们自己的业务方法,然后在方法上使用定义好的注解来标识,这样我们就可以在申请权限后通过反射Activity或Fragment,拿到标识了权限注解的方法,进行调用。完整代码如下:

1、定义注解

权限申请成功后调用的方法

/**
* 标识权限获取成功
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PermissionSuccess {
int requestCode();
}


申请被用户拒绝后调用的方法
/**
* 标识权限获取失败
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PermissionFail {
int requestCode();
}


2、权限工具类
public class PermissionUtil {

public static void needPermission(Fragment context, int reqCode, String... permissions) {
checkPermission(context, reqCode, permissions);
}

public static void needPermission(Activity context, int reqCode, String... permissions) {
checkPermission(context, reqCode, permissions);
}

@TargetApi(Build.VERSION_CODES.M)
private static void checkPermission(Object context, int reqCode, String... permissions) {

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
//6.0以下
executeSuccessResult(context, reqCode);
return;
}
boolean granted = hasPermission(context, permissions);//检查权限
if (granted) {
executeSuccessResult(context, reqCode);
} else {
if (context instanceof Fragment) {
((Fragment) context).requestPermissions(permissions, reqCode);
} else {
((Activity) context).requestPermissions(permissions, reqCode);
}
}
}

private static void executeSuccessResult(Object context, int reqCode) {
Method successMethod = getTargetMethod(context, reqCode, PermissionSuccess.class);
try {
successMethod.invoke(context);
} catch (Exception e) {
e.printStackTrace();
}
}

private static void executeFailResult(Object context, int reqCode) {
Method successMethod = getTargetMethod(context, reqCode, PermissionFail.class);
try {
successMethod.invoke(context);
} catch (Exception e) {
e.printStackTrace();
}
}

private static Method getTargetMethod(Object context, int reqCode, Class annotation) {
Method[] declaredMethods = context.getClass().getDeclaredMethods();
for (Method method : declaredMethods) {
if (!method.isAccessible()) {
method.setAccessible(true); //私有的方法必须强制
}
//判断方法上是否使用了目标注解
boolean annotationPresent = method.isAnnotationPresent(annotation);
if (annotationPresent) {
if (isTargetMethod(method, reqCode, annotation)) { //比较requestCode是否相等
return method;
}
}
}
return null;
}

private static boolean isTargetMethod(Method method, int reqCode, Class cls) {
if (cls.equals(PermissionSuccess.class)) {
return reqCode == method.getAnnotation(PermissionSuccess.class).requestCode();
} else if (cls.equals(PermissionFail.class)) {
return reqCode == method.getAnnotation(PermissionFail.class).requestCode();
}
return false;
}

private static boolean hasPermission(Object context, String... permissions) {
Activity activity = null;
if (context instanceof Fragment) {
activity = ((Fragment) context).getActivity();
} else {
activity = (Activity) context;
}
for (String permission : permissions) {
int granted = ContextCompat.checkSelfPermission(activity, permission);
if (granted == PackageManager.PERMISSION_DENIED) {
return false;
}
}
return true;
}

public static void onRequestPermissionsResult(Fragment context, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
handlePermissionsResult(context, requestCode, permissions, grantResults);
}

public static void onRequestPermissionsResult(Activity context, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
handlePermissionsResult(context, requestCode, permissions, grantResults);
}

private static void handlePermissionsResult(Object context, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
boolean permissionGranted = true;
for (int grant : grantResults) {
if (grant == PackageManager.PERMISSION_DENIED) {
permissionGranted = false;
break;
}
}
if (permissionGranted) {
//获得权限
executeSuccessResult(context, requestCode);
} else {
//权限被用户拒绝
executeFailResult(context, requestCode);
}
}
}


下载完整Demo 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息