android权限适配 简书,EasyPermissions Android权限适配(带流程图)

前言

阅读前说明:

所有系统均为Android原生系统,其他国产ROM最后再讨论。

所有的申请都为主动触发,即主动点击申请按钮。

申请时,默认是没有权限的。

流程图中长方形中为方法名。

流程图

申请单个权限流程图

f8776e1f5566

img

申请权限组流程图

f8776e1f5566

img

申请混合权限(单个权限+权限组)流程图

具体流程=单个权限流程图+权限组流程图

代码中有例子,就不详细说明了。

EasyPermissions使用

依赖

dependencies {

implementation 'pub.devrel:easypermissions:1.2.0'

}

检查权限并申请权限

public static final int PERMISSION_STORAGE_CODE = 10001;

public static final String PERMISSION_STORAGE_MSG = "此app需要获取SD卡读取权限";

public static final String[] PERMISSION_STORAGE = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE};

public static boolean hasPermissions(Context context, String... permissions) {

return EasyPermissions.hasPermissions(context, permissions);

}

/**

* 是否有SD卡权限

*

* @param context

* @return

*/

public static boolean hasStoragePermission(Context context) {

return hasPermissions(context, PERMISSION_STORAGE);

}

@AfterPermissionGranted(PERMISSION_STORAGE_CODE)

public void initSimple() {

if (hasStoragePermission(context)) {

//有权限

} else {

//申请权限

EasyPermissions.requestPermissions(context, PERMISSION_STORAGE_MSG, PERMISSION_STORAGE_CODE, PERMISSION_STORAGE);

}

}

实现EasyPermissions.PermissionCallbacks接口,直接处理权限是否成功申请

@Override

public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

super.onRequestPermissionsResult(requestCode, permissions, grantResults);

// Forward results to EasyPermissions

EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);

}

//成功

@Override

public void onPermissionsGranted(int requestCode, List list) {

// Some permissions have been granted

// ...

}

//失败

@Override

public void onPermissionsDenied(int requestCode, List list) {

// Some permissions have been denied

// ...

}

Dailog说明

RationaleDialog:申请权限的说明。

[图片上传失败...(image-da33d8-1530149961979)]

EasyPermissions.requestPermissions(context, PERMISSION_STORAGE_MSG, PERMISSION_STORAGE_CODE, PERMISSION_STORAGE);

或者

EasyPermissions.requestPermissions(

new PermissionRequest.Builder(this, RC_CAMERA_AND_LOCATION, perms)

.setRationale(R.string.camera_and_location_rationale)

.setPositiveButtonText(R.string.rationale_ask_ok)

.setNegativeButtonText(R.string.rationale_ask_cancel)

.setTheme(R.style.my_fancy_style)

.build());

方法回调实现EasyPermissions.RationaleCallbacks接口:

/**

* dialog提醒点击“确定”

*

* @param requestCode

*/

@Override

public void onRationaleAccepted(int requestCode) {

}

/**

* dialog提醒点击“取消”

*

* @param requestCode

*/

@Override

public void onRationaleDenied(int requestCode) {

}

AppSettingsDialog:跳转setting页,申请被拒绝时使用。

f8776e1f5566

AppSettingsDialog

/**

* 拒绝权限

*

* @param requestCode

* @param perms

*/

@Override

public void onPermissionsDenied(int requestCode, @NonNull List perms) {

if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {

new AppSettingsDialog.Builder(this)

.setTitle("提醒")

.setRationale("此app需要这些权限才能正常使用")

.build()

.show();

}

}

方法回调

/**

/**

* 设置页面回调

*

* @param requestCode

* @param resultCode

* @param data

*/

@Override

public void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) {

if (PermissionUtils.hasStoragePermission(context)){

//有权限

}else{

//没有权限

}

}

}

国产ROM适配

国产ROM问题一直是最多的,申请权限的弹窗不按Android原生来,有时候允许权限了,回调却是走失败。

如果想适配国产ROM,我推荐 AndPermission

AndPermission概述

AndPermission可以简化在Android上请求权限的流程。

在Android6.0或者更高版本的系统中请求运行时权限。

在Android7.0或者更高版本的系统中分享私有文件。

在Android8.0或者更高版本的系统中安装Apk文件。

请求流程

为了兼容一些特殊中国产手机,AndPermission请求权限的流程是这样的:

发起请求

调用SDK Api判断是否有权限

┌─────────────┴─────────────┐

有权限 没权限

│ │

│ 使用SDK Api请求权限

│ │

│ 用户授权或者拒绝

└─────────────┬─────────────┘

执行权限相关代码

┌───────┴───────┐

正常 异常

│ │

onGranted() onDenied()

┌──────┴──────┐ │

正常 异常───────┘

申请流程的释义

可以看出AndPermission的申请流程和标准的申请流程大相径庭,这样做主要是因为以下几点原因。

兼容Android5.0的系统判断是否有权限。

部分设备上使用SDK的Api判断是否有权限时,无论是否有权限都返回true。

部分设备上无论用户点击同意还是拒绝都返回true。

部分设备在申请权限时并不会弹出授权Dialog,而是在执行权限相关代码时才会弹出授权Dialog。

特特特别注意:

因为部分权限(例如发送短信、打电话、接听/挂断电话等),AndPermission不能执行权限相关代码做测试,所以对于这一类权限在执行权限相关代码步骤仅仅使用了AppOpsManager做检测。因为极少部分国产机总是返回true,因此直接回调到onGranted()中让开发者执行相关代码来辅助AndPermission的整个流程,如果onGranted()方法发生异常,那么则认为是没有权限,所以重新回调到onDenied()方法中,如果onGranted()方法正常执行那么则认为有权限。这样一来刚好是一个完整的流程,也可以最大限度的兼容到更多异常的手机。

回调onGranted()时AndPermission对onGranted()方法做了try catch。这样做可以保证两点,第一点是防止部分手机返回错误状态时回调了onGranted()后的崩溃,第二点是防止部分手机需要真正执行权限相关代码时触发授权Dialog后被用户拒绝后的崩溃。而这两点都是没有权限,因此会重新回调到onDenied()中让开发者处理没权限的情况。

综上所述,如果onGranted()和onDenied()方法都被调用了,说明开发者的onGranted()方法发生了异常。

GitHub

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值