申请权限的一般步骤
- 判断是否有权限,如果有权限,直接进行下一步。
- 如果没有权限,则开始申请权限。
- 如果用户授权,进行下一步。
- 如果用户拒绝授权,后面再次申请权限,系统为了不打扰用户,将不会出现系统的权限弹窗。在用户拒绝授权后,需要弹窗提示用户必须授权才能访问当前功能,并引导用户到系统设置中打开相应的权限。
每次申请权限的时候,都需要经过以上几个步骤,当申请的权限越来越多,大量的重复代码就出现了。为了减少重复代码,我封装了一个权限请求框架。
权限请求框架
桃夭是鸿蒙系统上的一款权限请求框架,封装了权限请求逻辑,采用链式调用的方式请求权限,极大的简化了权限请求的代码,同时支持在UI
、UIAbility
、UIExtensionAbility
里面申请权限。需要注意的是,应用在UIExtensionAbility
申请授权时,需要在onWindowStageCreate
函数执行结束后或在onWindowStageCreate
函数回调中申请权限。
本项目基于开源鸿蒙5.0开发,最低兼容到API 12,请将DevEco Studio升级到最新版。
桃夭名称来源
桃夭一词出自古代第一部诗歌总集《诗经》中《诗经·桃夭》,“桃之夭夭,灼灼其华。”桃花怒放千万朵,色彩鲜艳红似火。
下载安装
ohpm install @shijing/taoyao
申请运行时权限
TaoYao.with(this)
.runtime()
// 要申请的权限
.permission(permissions)
.onGranted(() => {
// 权限申请成功
})
.onDenied(() => {
// 权限申请失败
})
.request()
申请权限变得如此之简单。
已废弃的两个权限
允许应用读取用户外部存储中的媒体文件信息
ohos.permission.READ_MEDIA
允许应用读写用户外部存储中的媒体文件信息
ohos.permission.WRITE_MEDIA
从5.0,API 12开始,上述两个权限已经废弃。推荐方案(无需申请权限):使用图片/视频选择器读取媒体库的图片与视频;使用保存控件保存媒体库的图片与视频。
其它功能
提供跳转到系统设置的方法。
下面这张图是系统权限设置页面。

下面这张图是系统权限设置弹窗。

在api 12之前,只能跳转到系统权限设置页面。从API 12开始,可以直接拉起权限设置弹框,引导用户授予权限。这样的好处是,当系统设置权限弹窗关闭后,可以直接知道是否有权限。
默认情况下,桃夭会拉起系统权限设置弹窗,当系统权限设置弹窗关闭后,会通过回调告知是否有权限。
但是,有可能拉起系统权限设置弹窗会失败,目前发现ohos.permission.READ_HEALTH_DATA读取健康数据权限无法直接拉起系统设置弹窗,只能跳转到系统设置页面。
当拉起系统权限设置弹窗失败后,会回调onFailed。当回调回调onFailed,如果还是想从系统设置页面回来后是否有权限,可以在onPageShow方法里面申请权限。
TaoYao
.showSystemPermissionDialog(this.context, this.permissions)
.onGranted(() => {
// 直接拉起系统权限设置弹窗后,用户授权
this.toast('直接拉起系统权限设置弹窗后,有权限了')
})
.onDenied(() => {
// 直接拉起系统权限设置弹窗后,用户未授权
this.toast('直接拉起系统权限设置弹窗后,没权限')
})
.onFailed(() => {
/*
* 拉起系统设置弹窗失败,无法直接判断用户是否在系统权限设置弹窗授权,
* 只能跳转到系统权限设置页面,可以在onPageShow方法里面申请权限。
* 目前发现ohos.permission.READ_HEALTH_DATA健康数据权限无法直接拉起系统设置弹窗,只能跳转到系统设置页面。
*/
console.log("拉起系统设置弹窗失败,无法直接判断用户是否在系统权限设置弹窗授权,只能跳转到系统设置页面")
})
申请通知权限,如果用户拒绝通知权限,只能跳转到系统设置页面,系统权限设置弹窗不支持通知权限
TaoYao.with(this.context)
.notification()
.permission()
.onGranted(() => {
// 通知权限申请成功
this.toast()
})
.onDenied(() => {
// 通知权限只能跳转到系统设置页面,系统权限设置弹窗不支持通知权限
TaoYao.goToSettingPage(this.context)
})
.request()
有的时候仅仅只需判断是否有运行时权限,并不申请权限。
/**
* 仅仅检测是否有权限,如果没有权限,不会申请权限
*
* @param permissions
* @returns true 有权限
*/
static hasPermission(permissions: Array<Permissions>): boolean {
const generalChecker = new GeneralChecker()
return generalChecker.hasPermission(permissions)
}
判断是否有通知权限,如果没有通知权限,不会申请通知权限
/**
* 判断是否有通知权限,如果没有通知权限,不会申请通知权限
*
* @returns true支持,false不支持
*/
static isNotificationEnabled(): Promise<boolean> {
return NotificationPermissionChecker.isNotificationEnabled()
}
判断是否支持分布式通知
/**
* 判断是否支持分布式通知
*
* @returns true支持,false不支持
*/
static isDistributedEnabled(): Promise<boolean> {
return NotificationPermissionChecker.isDistributedEnabled()
}
系统选择器
系统选择器已经获取了对应权限的预授权,开发者使用系统选择器时,无需再次申请权限也可临时受限访问对应的资源。例如,当应用需要读取用户图片时,可通过使用照片选择器,在用户选择所需要的图片资源后,直接返回该图片资源,而不需要授予应用读取图片文件的权限。
联系人选择器,通过联系人选择器获取联系人,不需要申请通讯录权限。
TaoYao.with(this.context)
.contact()
.onSuccess((data) => {
// 联系人列表
if (data.length > 0) {
// 联系人名称
console.log("yunfei", data[0].name?.fullName)
// 联系人号码
console.log("yunfei", data[0]?.phoneNumbers?.[0]?.phoneNumber)
}
})
.onError((err) => {
console.log(err.message)
})
.selectContacts(new ContactBuilder()
// 可以选择多个联系人
.setMultiSelect(true))
相机选择器,拉起系统相机不需要申请相机权限。
TaoYao.with(this.context)
.camera()
.onSuccess((uri) => {
// 拍照或者录像的文件沙箱路径
console.log(uri)
})
.onError((err) => {
console.log(err.stack)
})
.openSystemCamera(new CameraBuilder()
// 后置相机,默认使用后摄
.setCameraSelector(CameraSelector.CAMERA_POSITION_BACK)
// 可以只要拍照,只要录像,默认拍照和录像都有
.setUseCase([UseCase.PHOTO, UseCase.VIDEO])
// 文件保存路径,可以不设置
//.setSaveUri("")
// 录制视频最大时长,可以不设置
//.setVideoMaxDuration()
)
图片、视频选择器,拉起系统图库不需要申请存储权限,只能获取选中的图片、视频
TaoYao.with(this.context)
.media()
.onSuccess((uris) => {
uris.forEach((uri) => {
console.log("yunfei", uri)
})
})
.onError((err) => {
console.log(err.stack)
})
.select(new MediaBuilder()
// 选择媒体文件的最大数目
.setMaxSelectNumber(10)
// 可选择的媒体文件类型,图片类型、视频类型、图片和视频类型、动态照片类型
.setMediaMineType(MediaMimeType.IMAGE_VIDEO_TYPE)
)
文档选择器,拉起文档选择器不需要申请权限,只能获取选中的文档
TaoYao.with(this.context)
.document()
.onSuccess((uris) => {
uris.forEach((uri) => {
console.log("yunfei", uri)
})
})
.onError((err) => {
console.log(err.stack)
})
.select(new DocumentBuilder()
// 选择媒体文件的最大数目
.setMaxSelectNumber(10)
// 指定选择的文件或者目录路径(可选)
//.setDefaultFilePathUri("")
// 选择是否对指定文件或目录授权,true为授权,当为true时,defaultFilePathUri为必选参数,拉起文管授权界面;false为非授权,拉起常规文管界面(可选)
//.setAuthMode(false)
// 选择文件的后缀类型['后缀类型描述|后缀类型'](可选) 若选择项存在多个后缀名,则每一个后缀名之间用英文逗号进行分隔(可选),后缀类型名不能超过100,选择所有文件:'所有文件(*.*)|.*';
// 例如:['图片(.png, .jpg)|.png,.jpg', '文档|.txt', '视频|.mp4', '.pdf']
.setFileSuffixFilters(['文档|.docx'])
)
音频选择器,拉起音频选择器不需要申请权限,只能获取选中的音频
TaoYao.with(this.context)<br> .audio()<br> .onSuccess((uris) => {<br> uris.forEach((uri) => {<br> console.log("yunfei", uri)<br> })<br> })<br> .onError((err) => {<br> console.log(err.stack)<br> })<br> // 目前音频选择器不支持参数配置,默认可以选择所有类型的用户文件。<br> .select(new AudioBuilder())
实现原理
实现原理请查看实战鸿蒙,实现一款权限请求框架。
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=21656,转载请注明出处。
评论0