feat:鸿蒙元服务接入麦克风运行时权限申请
MICROPHONE 是 user_grant 权限, 上一提交补了 module.json5 的 reason 只解决 了编译校验, 运行时仍需弹窗申请, 否则录音功能不可用。 在 EntryAbility.onCreate 中调用 abilityAccessCtrl.requestPermissionsFromUser。 关键点: - AscfUIAbility 父类已定义 onCreate, 重写时必须调 super.onCreate(want, launchParam), 否则跳过 ascf runtime 初始化导致元服务白屏 - 选 onCreate 而非按需触发: 权限状态在 JS 侧 (uni.getRecorderManager) 读不到, 项目无现成 JS<->ArkTS 通道; 且 requestPermissionsFromUser 对已授权应用 直接 resolve 不弹窗, 实际只有首次启动打扰用户一次 - 降级: 未授权不影响浏览/下单/卡片, 仅语音不可用, 前端 voice-panel 会 showToast 提示 readme 4.3.3 补充该实现与踩坑说明, 4.3.4 移除已解决项。
This commit is contained in:
21
readme.md
21
readme.md
@@ -183,9 +183,26 @@ Error Message: The reason and usedScene attributes are mandatory for user_grant
|
||||
|
||||
📌 `reason` 文案必须是**用户可读的中文说明**,不能为空或写 `xxx description` 之类的占位文本,否则上架审核会被驳回。
|
||||
|
||||
📌 **改完 `reason` 还不够** —— `user_grant` 权限编译通过后,仍需在运行时弹窗申请,否则录音等功能不可用。本项目已在 [EntryAbility.ets](stub-app-projects/mp-harmony/entry/src/main/ets/entryability/EntryAbility.ets) 的 `onCreate` 中接入:
|
||||
|
||||
```ts
|
||||
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
|
||||
// 必须先调父类: ascf runtime 的初始化在 AscfUIAbility.onCreate 里, 漏掉会导致元服务白屏
|
||||
super.onCreate(want, launchParam);
|
||||
this.requestMicrophonePermission();
|
||||
}
|
||||
```
|
||||
|
||||
> ⚠️ **坑**:`AscfUIAbility` 父类**已定义** `onCreate`,重写时必须调 `super.onCreate(want, launchParam)`,否则 ascf runtime 初始化被跳过,元服务白屏。
|
||||
|
||||
📌 为什么在 `onCreate` 申请而不是"用户点录音时才申请":
|
||||
- 权限状态在 JS 侧(`uni.getRecorderManager`)读不到,项目里也没有现成的 JS ↔ ArkTS 通道,做不了按需触发
|
||||
- `requestPermissionsFromUser` 对已授权的应用直接 resolve 且**不弹窗**,所以实际只有首次启动打扰用户一次
|
||||
|
||||
📌 用户拒绝后的降级:不影响浏览/下单/卡片等其他功能,仅语音输入不可用;[ai-chat-voice-panel.vue](pages_tool/ai-chat/components/ai-chat-voice-panel.vue) 会 catch 到 recorder 错误并 `showToast` 提示用户。
|
||||
|
||||
#### 4.3.4 【待完善】⚠️
|
||||
- **运行时权限申请未接入**:entry 模块中暂未找到 `abilityAccessCtrl` / `requestPermissionsFromUser` 调用。`user_grant` 权限编译通过后仍需在运行时弹窗申请,否则录音等功能会静默失败。
|
||||
- **release 签名仍指向 debug 证书**:`build-profile.json5` 中 `release` 签名的 `profile` 仍是 `./cert-profile/qq/qqDebug.p7b`。本地调试无碍,但提交 AppGallery 前必须换成**发布证书 + release 类型 provisioning profile**,否则 AGC 校验会直接拒绝。
|
||||
- **release 签名仍指向 debug 证书**:`build-profile.json5` 中 `release` 签名的 `profile` 仍是 `./cert-profile/qq/qqDebug.p7b`,与 `default`(debug)共用同一份证书。本地调试无碍,但提交 AppGallery 前必须换成**发布证书 + release 类型 provisioning profile**,否则 AGC 校验会直接拒绝。
|
||||
|
||||
#### 4.3.5 【交付与最终发布】🔍
|
||||
1. 将生成的 `.zip` 文件发送给运维人员
|
||||
|
||||
@@ -1,4 +1,41 @@
|
||||
import { AscfUIAbility } from '@atomicservice/ascfapi';
|
||||
|
||||
export default class EntryAbility extends AscfUIAbility {
|
||||
}
|
||||
import { abilityAccessCtrl, AbilityConstant, Permissions, Want } from '@kit.AbilityKit';
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
import { AscfUIAbility } from '@atomicservice/ascfapi';
|
||||
|
||||
export default class EntryAbility extends AscfUIAbility {
|
||||
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
|
||||
// 必须先调父类: ascf runtime 的初始化在 AscfUIAbility.onCreate 里, 漏掉会导致元服务白屏
|
||||
super.onCreate(want, launchParam);
|
||||
this.requestMicrophonePermission();
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请麦克风权限 (ohos.permission.MICROPHONE, user_grant 类型)。
|
||||
*
|
||||
* 为什么放在 onCreate 而不是"用户点录音时才申请":
|
||||
* 1. 权限状态在 JS 侧 (uni.getRecorderManager) 读不到, 项目里也没有现成的
|
||||
* JS <-> ArkTS 通道, 做不了按需触发的条件判断;
|
||||
* 2. requestPermissionsFromUser 对已授权的应用直接 resolve 且不弹窗,
|
||||
* 所以实际只有首次启动会打扰用户一次, 之后每次冷启动都是无感的。
|
||||
*
|
||||
* 未授权时的降级行为:
|
||||
* - 不影响其他功能 (浏览/下单/卡片), 只是语音输入不可用;
|
||||
* - 前端 ai-chat-voice-panel.vue 会 catch 到 recorder 错误并 showToast 提示用户。
|
||||
*/
|
||||
private async requestMicrophonePermission(): Promise<void> {
|
||||
try {
|
||||
const atManager = abilityAccessCtrl.createAtManager();
|
||||
const result = await atManager.requestPermissionsFromUser(this.context, [Permissions.MICROPHONE]);
|
||||
const authResult = result.authResults[0];
|
||||
if (authResult === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
|
||||
console.info('[EntryAbility] MICROPHONE 已授权, 语音输入可用');
|
||||
} else {
|
||||
console.warn('[EntryAbility] MICROPHONE 未授权, 语音输入不可用 (不影响其他功能)');
|
||||
}
|
||||
} catch (err) {
|
||||
// 用户取消授权弹窗 / context 异常, 同样降级为"语音不可用", 不阻断启动
|
||||
const e = err as BusinessError;
|
||||
console.warn(`[EntryAbility] 申请麦克风权限异常: code=${e.code}, message=${e.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user