首页 / 行业
如何使用鸿蒙系统上权限请求框架桃夭
2021-11-10 09:34:00
桃夭是鸿蒙系统上的一款权限请求框架,对请求权限的代码进行高度封装,极大的简化了申请权限的代码逻辑,同时支持在 Ability、FractionAbility、AbilitySlice、Fractiion 里面申请权限。
建议大家把源码下载下来看看:https://gitee.com/zhongte/TaoYao
申请权限
申请权限的一般步骤如下:
判断是否有权限,如果有权限,直接进行下一步。
如果没有权限,可以弹窗告知用户申请权限的原因。
弹窗告知用户后,如果用户同意申请权限,则判断用户是否点击了不再提醒。
如果用户没有点击不再提醒,则开始申请权限。
如果用户点击了不再提醒,则弹窗告知用户去设置页面开启权限,用户点击弹窗后,跳转到设置页面。
重写 onRequestPermissionsFromUserResult 方法,判断用户是否授予权限。
桃夭的使用方式
如下代码,先添加依赖,然后你只需要告知权限请求框架你需要什么权限,权限请求框架就会告知你权限申请成功还是失败。你不需要手动判断是否有权限,不需要弹窗告知用户申请权限的原因,不需要判断用户是否点击了不再提醒,不需要跳转设置页面让用户开启权限,不需要重写 onRequestPermissionsFromUserResult 方法。框架把这些代码逻辑都给做了,你只需要关注权限申请成功还是失败。申请权限变得如此之简单。添加依赖:
api'io.gitee.zhongte1.0.1'
申请权限:
//申请多设备协同权限EasyPermission.requestPermission(this,EasyPermission.DISTRIBUTED_DATASYNC,newPermissionAction(){@OverridepublicvoidonGranted(Listpermissions) {//权限申请成功}@OverridepublicvoidonDenied(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*/@OverridepublicbooleanhasPermission(Contextcontext,Listpermissions) {for(Stringpermission:permissions){intresult=context.verifySelfPermission(permission);if(result==IBundleManager.PERMISSION_DENIED){//没有权限returnfalse;}}returntrue;}
③判断用户是否点击了不再提醒
通过上下文对象的 canRequestPermission 方法来判断用户是否点击了不再提醒。
/***用户是否点击了不在提醒**@parampermission权限*@return*/@OverridepublicbooleancanRequestPermission(Stringpermission){returnmContext.canRequestPermission(permission);}
④跳转到设置页面
如果用户点击了不再提醒,则可以跳转到设置页面让用户开启权限。
/***跳转到设置页面*/@OverridepublicvoidgotoSetting(){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";@OverridepublicvoidonStart(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);}@OverridepublicvoidonRequestPermissionsFromUserResult(intrequestCode,String[]permissions,int[]grantResults){super.onRequestPermissionsFromUserResult(requestCode,permissions,grantResults);//权限的回调方法Postman.send(permissions,grantResults);terminateAbility();}@OverrideprotectedvoidonAbilityResult(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 来判断用户是否授予权限。
@OverridepublicbooleanhasPermission(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*/@Overridepublicbooleantest(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(){@Overridepublicvoidrun(){capturer.stop();}},AUDIO_RECORDING_TIME);//没有发生异常,有权限returntrue;}catch(Exceptione){//发生异常,无权限returnfalse;}}
桃夭在判断用户是否授权时,上面的两种方式都使用了。至此,桃夭框架的原理基本上讲完。有兴趣的同学可以去看看源码。想要看懂源码,需要熟悉申请权限的一般步骤,桃夭其实就对这些步骤进行封装。另外还需熟悉面向接口编程、熟悉策略模式等常见设计模式。责任编辑:haq
最新内容
手机 |
相关内容
半导体主控技术:驱动自动驾驶革命的
半导体主控技术:驱动自动驾驶革命的引擎,自动驾驶,交通,自动驾驶系统,数据,车辆,自动,随着科技的不断进步,自动驾驶技术已经成为现实电容式触摸按键屏中应用的高性能触
电容式触摸按键屏中应用的高性能触摸芯片,芯片,位置,触摸屏,能力,响应,用户,电容式触摸按键屏(Capacitive Touch Key Screen)是一种常晶振在激光雷达系统中的作用
晶振在激光雷达系统中的作用,作用,系统,激光雷达,晶振,可靠性,选择,激光雷达(Lidar)是一种利用激光进行测距的技术,广泛应用于自动驾驶苹果即将推出Mac系列新品,或搭载3nm
苹果即将推出Mac系列新品,或搭载3nm M3芯片,芯片,搭载,推出,全新,市场,研发,近日,有关苹果即将推出新一代Mac系列产品的消息引起了广Arbe 4D成像雷达以高分辨率雷达技
Arbe 4D成像雷达以高分辨率雷达技术和先进处理技术消除“幽灵刹车”问题,刹车,成像,分辨率,系统,目标,数据,Arbe 4D成像雷达是一种浅析动力电池熔断器的基础知识及选
浅析动力电池熔断器的基础知识及选型,动力电池,时切,系统安全,作用,产品,系统,BA4558F-E2动力电池熔断器是用于保护动力电池系统安苹果发布M3系列新款MacBook Pro/iM
苹果发布M3系列新款MacBook Pro/iMac:业界首批PC 3nm芯片,新款,芯片,业界,核心,用户,性能,近日,苹果公司发布了M3系列新款MacBook Pro消除“间隙”:力敏传感器如何推动新
消除“间隙”:力敏传感器如何推动新颖的HMI设计,传感器,智能手机,交互,交互方式,操作,用户,随着科技的不断发展,人机交互界面(HMI)的设