HarmonyOS鸿蒙Next中uniapp适配,权限申请和检查应该如何实现?
HarmonyOS鸿蒙Next中uniapp适配,权限申请和检查应该如何实现? 【问题描述】我在进行uniapp的鸿蒙适配过程中,权限申请和检查应该如何实现?
【问题详情】我在进行uniapp的鸿蒙适配过程中,遇到了权限申请和检查的场景。目前uniapp官方文档中有说明如何进行鸿蒙权限的配置,但是并未给出如何进行鸿蒙权限的申请和检测。我想知道:
1、是否可以直接使用uniapp提供的uni.authorize向用户发起授权呢?我看文档中写的并不支持app的适配好像?
2、如何通uts来进行鸿蒙权限的检测和申请呢?以定位权限的申请为例,是否有demo可以让我参考一下?
【背景知识】
- HarmonyOS权限体系相对复杂,请认真阅读HarmonyOS应用权限管控。
- 应用权限申请按照操作路径可分为4类。
| 序号 | 授权方式 | 操作路径 | 说明 |
|---|---|---|---|
| 类型1 | 开放权限(系统授权) | 声明权限 > 访问接口 | 如INTERNET网络权限,无需用户同意,仅在module.json5的requestPermission中声明即可直接使用。 |
| 类型2 | 开放权限(用户授权) | 声明权限 > 向用户申请授权 > 访问接口 | 弹窗询问用户是否允许,如位置定位等。 |
| 类型3 | 受限开放权限 | 申请使用受限权限 > 声明权限 > 访问接口 | 在AGC上申请包含受限权限的profile并集成到工程中,如悬浮窗。 |
| 类型4 | 受限开放权限 | 申请使用受限权限 > 声明权限 > 向用户申请授权 > 访问接口 | 是类型2和类型3的并集。不仅要在AGC上申请包含受限权限的profile并集成到工程中,还需要弹窗询问用户是否允许,如读取通讯录。 |
【解决方案】
1. 声明权限
参考uni-app官方文档权限配置指南。
uni-app打包时,是把
harmony-configs\entry\src\main\module.json5文件级覆盖到包里,并非JSON节点级别覆盖。因此从unpackage目录的module.json5复制到harmony-configs\entry\src\main后,仅修改requestPermissions节点,其他节点不要删除。
2. 申请使用受限权限 请参考HarmonyOS官方文档申请使用受限权限。
3. 向用户申请授权
- 在harmonyos-configs的module.json5文件中声明权限。
- 写uni-app插件,在插件中使用UTSHarmony.requestSystemPermission申请权限。
- 在uni-app页面中引用插件并调用。
HarmonyOS uts插件uniapp官方开发指南:示例文档。
案例可参考giteedemo:hw-location 地图相关
更多关于HarmonyOS鸿蒙Next中uniapp适配,权限申请和检查应该如何实现?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
下面给出在ArkTS项目里,以及用 uni-app 做鸿蒙适配时的方法
核心结论:
- uni-app 目前(HBuilderX 3.9 及之前版本)的 uni.authorize 仅对小程序生效,App(含鸿蒙)端不会弹窗,也不会返回正确结果,必须自己用 UTS 写原生代码。
- 用 UTS 可以直接调用鸿蒙系统 Ability 的 requestPermissionsFromUser / verifySelfPermission,官方已给出完整 demo,下面把定位权限(ohos.permission.LOCATION)的{检测}
一、鸿蒙ArkTS做法
1. module.json5 里声明权限
"requestPermissions": [
{
"name": "ohos.permission.LOCATION",
"reason": "$string:location_reason", // 在 string.json 里写用途
"usedScene": {
"ability": ["EntryAbility"],
"when": "inuse"
}
}
]
2. 检测 + 申请
import abilityAccessCtrl from '@ohos.abilityAccessCtrl'
import bundle from '@ohos.bundle'
const PERM = 'ohos.permission.LOCATION'
// 1. 先检测
async function checkLocation(): Promise<boolean> {
const mgr = abilityAccessCtrl.createAtManager()
const tokenID = bundle.getBundleInfoForSelfSync(0).appInfo.accessTokenId
const result = mgr.verifyAccessTokenSync(tokenID, PERM)
return result === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED
}
// 2. 再申请
async function requestLocation(context): Promise<boolean> {
const mgr = abilityAccessCtrl.createAtManager()
const result = await mgr.requestPermissionsFromUser(context, [PERM])
return result.authResults[0] === 0 // 0 表示用户允许
}
// 用法
if (!await checkLocation()) {
const ok = await requestLocation(getContext(this))
console.info('用户最终是否同意:', ok)
}
二、uni-app 鸿蒙端用 UTS 的完整 demo(可直接放到项目 /utssdk 目录)
1. 目录结构
├─utssdk
│ ├─harmony
│ │ ├─permission.uts
│ ├─index.uts
2. /utssdk/index.uts (导出给 Vue 用)
// 统一导出,保持多端兼容
export function checkLocation(): Promise<boolean> {
// #ifdef APP-HARMONY
return require('./harmony/permission.uts').checkLocation()
// #endif
// #ifndef APP-HARMONY
return Promise.resolve(false)
// #endif
}
export function requestLocation(): Promise<boolean> {
// #ifdef APP-HARMONY
return require('./harmony/permission.uts').requestLocation()
// #endif
// #ifndef APP-HARMONY
return Promise.resolve(false)
// #endif
}
3. /utssdk/harmony/permission.uts (真正的鸿蒙实现)
import abilityAccessCtrl from '@ohos.abilityAccessCtrl'
import bundle from '@ohos.bundle'
const PERM = 'ohos.permission.LOCATION'
// 检测
export async function checkLocation(): Promise<boolean> {
const mgr = abilityAccessCtrl.createAtManager()
// uni-app 里 getContext() 直接拿到当前 Ability
const tokenID = bundle.getBundleInfoForSelfSync(0).appInfo.accessTokenId
const result = mgr.verifyAccessTokenSync(tokenID, PERM)
return result === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED
}
// 申请
export async function requestLocation(): Promise<boolean> {
const mgr = abilityAccessCtrl.createAtManager()
// getContext() 返回的是当前 FeatureAbility
const result = await mgr.requestPermissionsFromUser(getContext(), [PERM])
return result.authResults[0] === 0
}
4. Vue 页面里调用
<script setup>
import { checkLocation, requestLocation } from '@/utssdk/index.uts'
async function locate() {
const ok = await checkLocation()
if (!ok) {
const granted = await requestLocation()
if (!granted) {
uni.showToast({ title: '需要定位权限', icon: 'none' })
return
}
}
// 下面就可以安全地使用 plus.maps / uni.getLocation 等 API 了
}
</script>
三、常见坑提醒
- 务必在「module.json5」里同步声明权限,否则申请会直接被系统拒绝。
- 鸿蒙 3.2 之后定位权限拆成了 ohos.permission.LOCATION(精确) ohos.permission.APPROXIMATELY_LOCATION(粗略) 如果 targetSdkVersion≥9,需要 同时 申请两个权限并在 UI 上给出「精确/粗略」选项,否则上架审核会被打回。
- requestPermissionsFromUser 的回调数组顺序与传入顺序一致,别硬编码 authResults[0] 以外的下标。
- 真机调试时,如果之前点过"拒绝且不再询问",需要在系统设置里手动清掉数据再测,否则不会弹窗。
- 目前 uni-app 的 uni.getLocation、plus.maps 等内置模块在鸿蒙端 不会自动帮你申请权限,一定要先自行申请通过后再调用,否则直接抛异常。
在HarmonyOS鸿蒙Next中,UniApp适配权限申请需使用鸿蒙原生API。权限检查通过调用abilityAccessCtrl模块的verifyAccessToken方法实现,传入权限名返回授权状态。权限申请需在module.json5配置文件中声明所需权限,并在应用运行时动态请求。使用requestPermissionsFromUser方法触发系统授权弹窗,处理用户授权结果回调。权限管理遵循鸿蒙安全机制,确保应用合规访问设备资源。
在HarmonyOS Next中,UniApp的权限适配需通过UTS扩展实现,无法直接使用uni.authorize接口。以下是具体实现方案:
-
权限申请机制:
- 创建UTS插件,调用HarmonyOS的
abilityAccessCtrl模块 - 使用
requestPermissionsFromUser方法触发动态授权弹窗 - 通过
verifyAccessToken同步检查权限状态
- 创建UTS插件,调用HarmonyOS的
-
定位权限实现示例:
import { Permissions } from '@ohos.abilityAccessCtrl'
// 权限检查
const atManager = abilityAccessCtrl.createAtManager()
const status = atManager.verifyAccessToken(tokenId, permission.LOCATION)
// 权限申请
let permissions: Array<string> = [Permissions.LOCATION_IN_BACKGROUND]
atManager.requestPermissionsFromUser(context, permissions)
- 关键注意事项:
- 需在module.json5中声明requiredPermissions权限清单
- 权限弹窗文本需在resource/profile/main_resource.json配置
- 建议封装成统一权限管理模块供多端调用
建议参考HarmonyOS官方权限开发文档结合UTS语法规范进行具体实现。

