0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何使用鸿蒙系统上权限请求框架桃夭

OpenHarmony技术社区 来源:简书 作者:裴云飞 2021-11-10 09:34 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

桃夭是鸿蒙系统上的一款权限请求框架,对请求权限的代码进行高度封装,极大的简化了申请权限的代码逻辑,同时支持在 Ability、FractionAbility、AbilitySlice、Fractiion 里面申请权限。

建议大家把源码下载下来看看:
https://gitee.com/zhongte/TaoYao

申请权限

申请权限的一般步骤如下

  • 判断是否有权限,如果有权限,直接进行下一步。

  • 如果没有权限,可以弹窗告知用户申请权限的原因。

  • 弹窗告知用户后,如果用户同意申请权限,则判断用户是否点击了不再提醒。

  • 如果用户没有点击不再提醒,则开始申请权限。

  • 如果用户点击了不再提醒,则弹窗告知用户去设置页面开启权限,用户点击弹窗后,跳转到设置页面。

  • 重写 onRequestPermissionsFromUserResult 方法,判断用户是否授予权限。

每次申请权限的时候,都需要经过以上几个步骤,当申请的权限越来越多,大量的重复代码就出现了。

为了减少重复代码,我封装了一个权限请求框架,权限请求框架取名为桃夭。

桃夭的使用方式

如下代码,先添加依赖,然后你只需要告知权限请求框架你需要什么权限,权限请求框架就会告知你权限申请成功还是失败。

你不需要手动判断是否有权限,不需要弹窗告知用户申请权限的原因,不需要判断用户是否点击了不再提醒,不需要跳转设置页面让用户开启权限,不需要重写 onRequestPermissionsFromUserResult 方法。

框架把这些代码逻辑都给做了,你只需要关注权限申请成功还是失败。申请权限变得如此之简单。

添加依赖:

api'io.gitee.zhongte1.0.1'

申请权限:

//申请多设备协同权限
EasyPermission.requestPermission(this,EasyPermission.DISTRIBUTED_DATASYNC,newPermissionAction(){
@Override
publicvoidonGranted(Listpermissions){
//权限申请成功

}

@Override
publicvoidonDenied(Listpermissions){
//权限申请失败
}
},SystemPermission.DISTRIBUTED_DATASYNC);

申请权限的时候可能会涉及到两个弹窗,一个弹窗是用来告知用户申请权限的原因,另一个弹窗是用来告知用户去设置页面开启权限。

这两个弹窗在不同的应用里面可能长得不一样,所以这两个弹窗并没有被封装到桃夭框架里面,而是需要使用者根据你的弹窗样式对桃夭进行二次封装。

我在源码里面对桃夭框架进行了二次封装,大家可以把源码下载下来,参考下我是如何对桃夭框架进行二次封装的。二次封装完成后,就可以愉快的使用上面的代码申请权限了。

实现原理

①检测申请的权限是否在配置文件中声明

申请的权限必须在配置文件中声明,否则桃夭会直接抛异常。如何检测申请的权限是否在配置文件中声明。

如下代码,获取 bundleManager 对象,通过 bundleManager 对象获取应用信息,之后就可以获取应用在配置文件中声明的权限了。

/**
*获取在配置文件中声明的权限
*
*@paramcontext上下文
*@return在配置文件中声明的权限
*/
privateListgetConfigPermissions(Contextcontext){
//获取bundleManager对象
IBundleManagerbundleManager=context.getBundleManager();
StringbundleName=context.getBundleName();
try{
//获取应用信息
BundleInfobundleInfo=bundleManager.getBundleInfo(bundleName,IBundleManager.GET_BUNDLE_WITH_REQUESTED_PERMISSION);
//获取应用在配置文件中声明的权限
ListreqPermissionDetails=bundleInfo.reqPermissions;
if(reqPermissionDetails==null||reqPermissionDetails.isEmpty()){
thrownewIllegalStateException("请在配置文件中声明要申请的权限");
}
returnreqPermissionDetails;
}catch(RemoteExceptione){
e.printStackTrace();
}
returnnewArrayList<>();
}

获取到在配置文件中声明的权限后,就可以判断申请的权限是否在配置文件中了。

/**
*检查申请的权限是否在配置文件中声明
*
*@parampermissions要申请的权限
*/
privatevoidcheckPermissions(String...permissions){
if(permissions==null||permissions.length==0){
thrownewIllegalArgumentException("请至少申请一个权限");
}
//获取在配置文件中声明的权限
mReqPermissions=getConfigPermissions(mOrigin.getContext());
if(mReqPermissions.isEmpty()){
thrownewIllegalStateException("请在配置文件中声明要申请的权限");
}
for(Stringtarget:permissions){
if(!mReqPermissions.contains(target)){
//没有在配置中声明要申请的权限,直接抛异常
thrownewIllegalStateException(String.format("%1$s权限没有配置文件中声明",target));
}
}
}

②判断是否有权限

检测完权限是否在配置中声明后,就可以判断是否有权限了。这里就是通过上下文对象的 verifySelfPermission 方法来判断是否有权限,如果没有权限,可以弹窗告知用户申请的原因。

/**
*是否有权限
*
*@paramcontext
*@parampermissions
*@return
*/
@Override
publicbooleanhasPermission(Contextcontext,Listpermissions){
for(Stringpermission:permissions){
intresult=context.verifySelfPermission(permission);
if(result==IBundleManager.PERMISSION_DENIED){
//没有权限
returnfalse;
}
}
returntrue;
}

③判断用户是否点击了不再提醒

通过上下文对象的 canRequestPermission 方法来判断用户是否点击了不再提醒。

/**
*用户是否点击了不在提醒
*
*@parampermission权限
*@return
*/
@Override
publicbooleancanRequestPermission(Stringpermission){
returnmContext.canRequestPermission(permission);
}

④跳转到设置页面

如果用户点击了不再提醒,则可以跳转到设置页面让用户开启权限。

/**
*跳转到设置页面
*/
@Override
publicvoidgotoSetting(){
try{
Intentintent=newIntent();
intent.setAction(IntentConstants.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setUri(Uri.parse("package:"+mOrigin.getContext().getBundleName()));
mOrigin.startAbility(intent);
}catch(Exceptione){
e.printStackTrace();
}
}

⑤启动透明的 Ability 申请权限

如果没有权限,用户页面没有点击不再提醒,那就可以申请权限了。为了不让调用者重写 onRequestPermissionsFromUserResult 方法,桃夭内部启动了一个 Ability。

如下代码:

/**
*开启一个透明的Ability来申请权限,这样外界就不需要重写onRequestPermissionsFromUserResult方法
*/
publicclassPermissionAbilityextendsAbility{

privatestaticfinalintREQUEST_CODE=0X10;
publicstaticfinalStringKEY_PERMISSION="key_permission";
publicstaticfinalStringKEY_TYPE="key_type";
publicstaticfinalStringSENSITIVE_PERMISSION="sensitive_permission";

@Override
publicvoidonStart(Intentintent){
super.onStart(intent);
getWindow().setTransparent(true);
super.setUIContent(ResourceTable.Layout_ability_permission);
Listpermissions=intent.getSerializableParam(KEY_PERMISSION);
StringpermissionType=intent.getStringParam(KEY_TYPE);
//请求权限
requestPermissionsFromUser(permissions.toArray(newString[0]),REQUEST_CODE);
}

@Override
publicvoidonRequestPermissionsFromUserResult(intrequestCode,String[]permissions,int[]grantResults){
super.onRequestPermissionsFromUserResult(requestCode,permissions,grantResults);
//权限的回调方法
Postman.send(permissions,grantResults);
terminateAbility();
}

@Override
protectedvoidonAbilityResult(intrequestCode,intresultCode,IntentresultData){
super.onAbilityResult(requestCode,resultCode,resultData);
}
}

直接启动一个 Ability 会发生页面跳转,为了不让页面发生跳转,这里启动了一个透明的 Ability。

如何将 Ability 设置透明,如下代码。在 abilities 节点添加 metaData,这里最关键的是 Translucent,也就是透明。

"abilities":[
{
"orientation":"unspecified",
"name":"com.poetry.taoyao.ability.PermissionAbility",
"icon":"$media:icon",
"description":"$string:permissionability_description",
"label":"$string:taoyao_PermissionAbility",
"type":"page",
"launchType":"standard",
"metaData":{
"customizeData":[
{
"name":"hwc-theme",
"value":"androidhwext:style/Theme.Emui.Translucent.NoTitleBar"
}
]
}
}

仅仅有上面的步骤好不够,需要在 Ability 或者 AbilitySlice 里面将窗口设置成透明。

如下代码:

getWindow().setTransparent(true);

经过上面两步,也就是将 Ability 的主题和窗口都设置成透明,这样就能将 Ability 变成透明的了,同时也不会发生页面跳转。

⑥判断用户是否授予权限

判断用户是否授予权限,可以使用标准的方式来判断。也就是通过 grantResult 来判断用户是否授予权限。

@Override
publicbooleanhasPermission(int[]grantResults,String...permissions){
if(grantResults==null||grantResults.length<= 0){
returnfalse;
}
for(intgrantResult:grantResults){
if(grantResult==IBundleManager.PERMISSION_DENIED){
returnfalse;
}
}
returntrue;
}

其实还有另外的方式来判断用户是否授予权限。也就是不管用户是否授权,直接访问相关业务。

比如,申请录音权限,当系统回调 onRequestPermissionsFromUserResult 方法时,直接去录音,如果发生异常,捕获异常说明没有权限。

如下代码:

/**
*通过直接录音的方式来判断是否有录音权限
*
*@paramcontext
*@return
*@throwsThrowable
*/
@Override
publicbooleantest(Contextcontext)throwsThrowable{
AudioStreamInfoaudioStreamInfo=newAudioStreamInfo.Builder().encodingFormat(
AudioStreamInfo.EncodingFormat.ENCODING_PCM_16BIT)
.channelMask(AudioStreamInfo.ChannelMask.CHANNEL_IN_STEREO)
.sampleRate(AUDIO_SAMPLE_RATE)
.build();
AudioCapturerInfoaudioCapturerInfo=newAudioCapturerInfo.Builder().audioStreamInfo(audioStreamInfo).build();
try{
AudioCapturercapturer=newAudioCapturer(audioCapturerInfo);
//录音
capturer.start();
newTimer().schedule(newTimerTask(){
@Override
publicvoidrun(){
capturer.stop();
}
},AUDIO_RECORDING_TIME);
//没有发生异常,有权限
returntrue;
}catch(Exceptione){
//发生异常,无权限
returnfalse;
}
}

桃夭在判断用户是否授权时,上面的两种方式都使用了。至此,桃夭框架的原理基本上讲完。有兴趣的同学可以去看看源码。

要看懂源码,需要熟悉申请权限的一般步骤,桃夭其实就对这些步骤进行封装。另外还需熟悉面向接口编程、熟悉策略模式等常见设计模式。
责任编辑:haq
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 操作系统
    +关注

    关注

    37

    文章

    7329

    浏览量

    128651
  • 鸿蒙系统
    +关注

    关注

    183

    文章

    2642

    浏览量

    69349
  • HarmonyOS
    +关注

    关注

    80

    文章

    2146

    浏览量

    35588

原文标题:一款好用的鸿蒙权限请求框架!

文章出处:【微信号:gh_834c4b3d87fe,微信公众号:OpenHarmony技术社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    开源鸿蒙技术大会2025丨开源鸿蒙应用开发再提速,跨平台框架PMC(筹)正式启动孵化

    9月27日,开源鸿蒙技术大会2025在长沙国际会议中心盛大举办。大会现场,开源鸿蒙跨平台框架PMC(筹)正式启动孵化,标志着开源鸿蒙在应用开发基础设施建设层面迎来重大里程碑,也为整个行
    的头像 发表于 11-10 18:15 1091次阅读
    开源<b class='flag-5'>鸿蒙</b>技术大会2025丨开源<b class='flag-5'>鸿蒙</b>应用开发再提速,跨平台<b class='flag-5'>框架</b>PMC(筹)正式启动孵化

    知乎开源“智能预渲染框架” 几行代码实现鸿蒙应用页面“秒开”

    近日,知乎在Gitee平台开源了其自研的鸿蒙“智能预渲染框架”,并将该框架的Har包上架到OpenHarmony三方库中心仓。该框架鸿蒙
    的头像 发表于 08-29 14:32 472次阅读
    知乎开源“智能预渲染<b class='flag-5'>框架</b>” 几行代码实现<b class='flag-5'>鸿蒙</b>应用页面“秒开”

    技术文章 | Ubuntu权限管理攻略

    前言:在Linux系统生态中,Ubuntu凭借其易用性和稳定性成为众多开发者与企业的首选操作系统。而权限管理作为Ubuntu系统安全的核心支柱,直接决定了
    的头像 发表于 08-14 12:02 670次阅读
    技术文章 | Ubuntu<b class='flag-5'>权限</b>管理攻略

    NVMe高速传输之摆脱XDMA设计18:PCIe请求模块设计(

    请求模块的具体任务是将系统请求转换成为axis接口形式的TLP或配置管理接口信号。这些请求主要包含初始化配置请求和门铃写
    的头像 发表于 08-09 14:52 4651次阅读
    NVMe高速传输之摆脱XDMA设计18:PCIe<b class='flag-5'>请求</b>模块设计(<b class='flag-5'>上</b>)

    NVMe高速传输之摆脱XDMA设计之12:PCIe请求模块设计(

    请求模块负责将系统请求转换为AXIS接口的TLP信号或配置管理接口信号,处理初始化配置请求和门铃写请求。初始化
    的头像 发表于 08-04 09:52 522次阅读
    NVMe高速传输之摆脱XDMA设计之12:PCIe<b class='flag-5'>请求</b>模块设计(<b class='flag-5'>上</b>)

    中软国际正式启动鸿蒙软件工场

    自2024年HarmonyOS NEXT版本起,HarmonyOS应用框架层更新为鸿蒙“单框架”,正式告别了对Android应用框架、内核的依赖。2025年,
    的头像 发表于 06-17 15:44 806次阅读

    Kuikly鸿蒙版正式开源 —— 揭秘卓越性能适配之旅

    、腾讯新闻、搜狗输入法、全民K歌、自选股等。 鸿蒙适配效果 Kuikly以高性能、动态化为框架核心目标。在鸿蒙Next系统推出后,Kuikly较早投入适配工作,得益于轻量渲染架构的设计
    发表于 06-04 16:46

    Linux权限管理基础入门

    在Linux的广阔天空中,权限管理犹如一只翱翔的雄鹰,掌控着系统的安全与秩序。掌握Linux权限,不仅能让你的系统管理更加得心应手,还能有效防止未授权访问和数据泄露。本文将带你深入探索
    的头像 发表于 05-06 13:44 555次阅读
    Linux<b class='flag-5'>权限</b>管理基础入门

    鸿蒙应用元服务开发-Account Kit配置登录权限

    一、场景介绍 华为账号登录是基于OAuth 2.0协议标准和OpenID Connect协议标准构建的OAuth2.0 授权登录系统,元服务可以方便地获取华为账号用户的身份标识,快速建立元服务内
    发表于 04-15 16:03

    鸿蒙应用元服务开发-Account Kit配置scope权限

    : 使用场景类型:参见表1,补充描述说明(若为表1以外场景,请按实际类型填写)。 业务场景描述:参见表1,补充描述说明(若为表1以外场景,请按实际场景填写)。 实际使用说明:描述该权限的使用流程和每秒请求
    发表于 04-11 15:50

    【「鸿蒙操作系统设计原理与架构」阅读体验】01-初始华为鸿蒙

    的应用经验,已形成了一套较完备的理论体系。鸿蒙操作系统在该理论体系的基础,结合我国多年的产业化经验,参考学术界的最新研究成果,完成了基础架构设计。鸿蒙操作
    发表于 01-25 11:05

    云天励飞DeepEdge10芯片与国产鸿蒙操作系统完成适配

    日前,DeepEdge10芯片已完成国产鸿蒙操作系统的适配。目前已构建适配鸿蒙的芯片编译平台框架,完成图形等子系统的适配。基于DeepEdg
    的头像 发表于 01-24 10:14 1704次阅读

    鸿蒙原生页面高性能解决方案上线OpenHarmony社区 助力打造高性能原生应用

    。 HMrouter:简化页面跳转逻辑HMrouter是HarmonyOS NEXT出色的路由框架解决方案,专注于优化应用内原生页面跳转逻辑,它封装系统 Navigation,集成
    发表于 01-02 18:00

    linux权限管理详解

    权限:在计算机系统中,权限是指某个计算机用户具有使用软件资源的权利。
    的头像 发表于 12-25 09:43 1107次阅读

    名单公布!【书籍评测活动NO.53】鸿蒙操作系统设计原理与架构

    827亿次/月。 HarmonyOS 实现了一个系统,统一所有设备生态。 鸿蒙原生应用已进入全面冲刺阶段, 5000多个常用应用已全部启动开发,其中超过1500家已完成架。 对开发者而言,真的做到
    发表于 12-16 15:10