一、申请权限的一般步骤
- 判断是否有权限,如果有权限,直接进行下一步。
- 如果没有权限,则开始申请权限。
- 如果用户授权,进行下一步。
- 如果用户拒绝授权,后面再次申请权限,系统为了不打扰用户,将不会出现系统的权限弹窗。在用户拒绝授权后,需要弹窗提示用户必须授权才能访问当前功能,并引导用户到系统设置中打开相应的权限。
每次申请权限的时候,都需要经过以上几个步骤,当申请的权限越来越多,大量的重复代码就出现了。为了减少重复代码,我封装了一个权限请求框架。
二、权限请求框架
桃夭是鸿蒙系统上的一款权限请求框架,封装了权限请求逻辑,采用链式调用的方式请求权限,极大的简化了权限请求的代码,同时支持在UI
、UIAbility
、UIExtensionAbility
里面申请权限。需要注意的是,应用在UIExtensionAbility
申请授权时,需要在onWindowStageCreate函数执行结束后或在onWindowStageCreate
函数回调中申请权限。
本项目基于开源鸿蒙4.1开发,最低兼容到API 11,请将DevEco Studio升级到最新版,DevEco Studio版本低于5.0.3.403可能无法编译。
三、桃夭名称来源
桃夭一词出自古代第一部诗歌总集《诗经》中《诗经·桃夭》,“桃之夭夭,灼灼其华。”桃花怒放千万朵,色彩鲜艳红似火。
四、桃夭的使用方式
下载
ohpm install @shijing/taoyao
申请权限
TaoYao.with(this)
.runtime()
// 要申请的权限
.permission(permissions)
.onGranted(() => {
// 权限申请成功
})
.onDenied(() => {
// 权限申请失败
})
.request()
申请权限变得如此之简单。
五、实现原理
5、1 如何支持在UI
、UIAbility
、UIExtensionAbility
里面申请权限。
可以使用联合类型,也可以使用重载。这里通过重载的方式来实现在UI
、UIAbility
、UIExtensionAbility
里面申请权限。
/**
* 直接在UIExtensionAbility中申请权限
*
* @param uiAbility
* @returns
*/
static with(extensionAbility: UIExtensionAbility): IAccessControl;
/**
* 在UI中向用户申请授权
*
* @param context
* @returns
*/
static with(context: common.UIAbilityContext): IAccessControl;
/**
* 直接在UIAbility中申请权限
*
* @param uiAbility
* @returns
*/
static with(uiAbility: UIAbility): IAccessControl;
static with(context: common.UIAbilityContext | UIAbility | UIExtensionAbility): IAccessControl {
if (context instanceof UIAbility) {
return new AccessControl(new UIAbilityOrigin(context))
} else if (context instanceof UIExtensionAbility) {
return new AccessControl(new UIExtensionAbilityOrigin(context))
} else {
return new AccessControl(new ContextOrigin(context))
}
}
UI
、UIAbility
、UIExtensionAbility
里面最重要就是Context
对象,申请权限的时候需要传入Context
对象,我们需要从UI
、UIAbility
、UIExtensionAbility
里面获取Context
对象。
这里采用策略模式。创建接口Origin
,Origin
代表从哪申请权限,定义getContext
方法,由子类实现该方法。
/**
* 需要UI、UIAbility、UIExtensionAbility申请权限,同时获取Context对象。
*/
export interface Origin {
/**
* 获取context对象
*
* @returns
*/
getContext(): Context
}
ContextOrigin
代表在在UI中申请权限,实现Origin
接口,重写getContext
方法。
/**
* 在UI中申请权限
*/
export class ContextOrigin implements Origin {
private context: common.UIAbilityContext
constructor(context: common.UIAbilityContext) {
this.context = context
}
getContext(): Context {
return this.context
}
}
UIAbilityOrigin
代表在在UIAbility
中申请权限,同样实现Origin
接口,重写getContext
方法。
/**
* 在UIAbility中申请权限
*/
export class UIAbilityOrigin implements Origin {
priv