HarmonyOS鸿蒙Next中uniapp适配,权限申请和检查应该如何实现?

HarmonyOS鸿蒙Next中uniapp适配,权限申请和检查应该如何实现? 【问题描述】我在进行uniapp的鸿蒙适配过程中,权限申请和检查应该如何实现?

【问题详情】我在进行uniapp的鸿蒙适配过程中,遇到了权限申请和检查的场景。目前uniapp官方文档中有说明如何进行鸿蒙权限的配置,但是并未给出如何进行鸿蒙权限的申请和检测。我想知道:

1、是否可以直接使用uniapp提供的uni.authorize向用户发起授权呢?我看文档中写的并不支持app的适配好像?

2、如何通uts来进行鸿蒙权限的检测和申请呢?以定位权限的申请为例,是否有demo可以让我参考一下?

4 回复

【背景知识】

  1. HarmonyOS权限体系相对复杂,请认真阅读HarmonyOS应用权限管控
  2. 应用权限申请按照操作路径可分为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. 向用户申请授权

  1. 在harmonyos-configs的module.json5文件中声明权限。
  2. 写uni-app插件,在插件中使用UTSHarmony.requestSystemPermission申请权限。
  3. 在uni-app页面中引用插件并调用。

HarmonyOS uts插件uniapp官方开发指南:示例文档

案例可参考giteedemo:hw-location 地图相关

更多关于HarmonyOS鸿蒙Next中uniapp适配,权限申请和检查应该如何实现?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


下面给出在ArkTS项目里,以及用 uni-app 做鸿蒙适配时的方法

核心结论:

  1. uni-app 目前(HBuilderX 3.9 及之前版本)的 uni.authorize 仅对小程序生效,App(含鸿蒙)端不会弹窗,也不会返回正确结果,必须自己用 UTS 写原生代码。
  2. 用 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>

三、常见坑提醒

  1. 务必在「module.json5」里同步声明权限,否则申请会直接被系统拒绝。
  2. 鸿蒙 3.2 之后定位权限拆成了 ohos.permission.LOCATION(精确) ohos.permission.APPROXIMATELY_LOCATION(粗略) 如果 targetSdkVersion≥9,需要 同时 申请两个权限并在 UI 上给出「精确/粗略」选项,否则上架审核会被打回。
  3. requestPermissionsFromUser 的回调数组顺序与传入顺序一致,别硬编码 authResults[0] 以外的下标。
  4. 真机调试时,如果之前点过"拒绝且不再询问",需要在系统设置里手动清掉数据再测,否则不会弹窗。
  5. 目前 uni-app 的 uni.getLocation、plus.maps 等内置模块在鸿蒙端 不会自动帮你申请权限,一定要先自行申请通过后再调用,否则直接抛异常。

在HarmonyOS鸿蒙Next中,UniApp适配权限申请需使用鸿蒙原生API。权限检查通过调用abilityAccessCtrl模块的verifyAccessToken方法实现,传入权限名返回授权状态。权限申请需在module.json5配置文件中声明所需权限,并在应用运行时动态请求。使用requestPermissionsFromUser方法触发系统授权弹窗,处理用户授权结果回调。权限管理遵循鸿蒙安全机制,确保应用合规访问设备资源。

在HarmonyOS Next中,UniApp的权限适配需通过UTS扩展实现,无法直接使用uni.authorize接口。以下是具体实现方案:

  1. 权限申请机制

    • 创建UTS插件,调用HarmonyOS的abilityAccessCtrl模块
    • 使用requestPermissionsFromUser方法触发动态授权弹窗
    • 通过verifyAccessToken同步检查权限状态
  2. 定位权限实现示例

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)
  1. 关键注意事项
    • 需在module.json5中声明requiredPermissions权限清单
    • 权限弹窗文本需在resource/profile/main_resource.json配置
    • 建议封装成统一权限管理模块供多端调用

建议参考HarmonyOS官方权限开发文档结合UTS语法规范进行具体实现。

回到顶部