【听见课堂 HarmonyOS NEXT 实战系列 32】相机权限被拒绝后,扫描功能如何继续可用
【听见课堂 HarmonyOS NEXT 实战系列 32】相机权限被拒绝后,扫描功能如何继续可用
权限被拒绝不应等于功能页面报废。对课堂扫描来说,拍照只是图片输入方式之一;图库选择、人工录入和明确标识的本地示例仍能完成复核与保存。真正稳健的设计,是把权限状态限制在需要它的动作上,而不是把整个 OCR 业务链路锁死。
听见课堂当前在 ScanCaptureService.requestCameraPermission() 中对 ohos.permission.CAMERA 做运行时判断,P05 页面同时保留系统图库和本地示例。本文按项目现状拆解权限分支,并结合当前官方 CameraPicker 建议说明这道门禁为何还值得复核。

一、权限只约束拍照动作
页面的“拍照扫描”调用 captureFromCamera(),图库入口调用 selectFromGallery(),本地示例调用 useLocalScanDemo()。三条路径没有被一个全局 hasCameraPermission 同时禁用。
这种结构确保权限拒绝只影响拍照,而不会让用户失去全部扫描整理能力。
二、项目当前怎样查询权限
const manager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
const status = manager.getSelfPermissionStatus(CAMERA_PERMISSION);
if (status === abilityAccessCtrl.PermissionStatus.GRANTED) {
return true;
}
if (status === abilityAccessCtrl.PermissionStatus.DENIED) {
return false;
}
已经授权直接继续,明确拒绝直接返回,不反复弹窗。页面可根据错误映射引导用户选择替代路径。
三、未决状态才发起运行时申请
const result: PermissionRequestResult = await manager.requestPermissionsFromUser(
context,
[CAMERA_PERMISSION]
);
const granted: boolean = result.authResults.length > 0 && result.authResults[0] === 0;
申请发生在用户点击“拍照扫描”之后,而不是应用启动时。用途、时机和行为有明确对应关系。
四、异常时默认按未授权处理
权限 API 自身也可能抛异常。Service 捕获后记录警告并返回 false:
} catch (error) {
hilog.warn(DOMAIN, TAG, 'Camera permission request failed: %{public}s', JSON.stringify(error));
return false;
}
在隐私边界上采用失败关闭更安全;不能因为权限管理器异常就继续访问能力。
五、页面如何识别权限失败
底层抛出 camera permission denied.,页面统一交给 scanFailureMessage():
if (detail.includes('permission') || detail.includes('denied')) {
return action + '未完成,可能是系统权限被拒绝。' +
'你可以检查权限、从图库选择,或使用本地示例继续验收。';
}
它没有把权限拒绝写成“设备坏了”,也没有承诺后台自动恢复。
六、为什么必须提供图库入口
用户可能已经拍好板书照片,或者学校策略禁止应用调用相机。PhotoViewPicker 让用户主动选择单张图片,扫描流程仍可进入 OCR。
图库入口不是“次等模式”,而是与拍照并列的输入方式。后续文本复核、来源标记和保存逻辑应完全共用。
七、本地示例解决的是验收,不是真实识别
本地示例载入预置的扫描记录和文字,目标是让用户在没有相机、没有图库图片或模拟器环境中体验 P06 校对、翻页、时间关联与数据库保存。
界面明确显示“本地示例”,来源写入 P05 本地扫描演示。它不能被统计为 CameraPicker 成功,也不能作为 Core Vision OCR 准确率证据。
八、人工输入是失败后的真实出口
真实图片已经载入但 OCR 失败时,页面保留临时预览,把 ocrText 置空并显示:
自动识别未完成,原图仍可在本页临时预览。请手动录入文字,或返回重新扫描。
用户补全后仍可保存复核文本。系统不伪造识别结果,也不丢弃用户已选择的图片上下文。

九、恢复动作要分层
建议按成本从低到高给出:
- 当前页面直接改用图库;
- 使用本地示例了解后续流程;
- 进入系统设置检查权限;
- 重试拍照;
- 若系统能力持续不可用,记录设备与错误码。
不能只弹“请开启权限”,然后把用户留在死路里。
十、不要扩大到相册读写权限
项目 module.json5 只声明麦克风和相机,没有 READ_IMAGEVIDEO 或 WRITE_IMAGEVIDEO。图库通过系统 Picker 选择,应用只处理用户明确挑选的 URI。
为了补救相机拒绝而申请整个媒体库权限,会把一个局部问题扩大成更高隐私和审核成本。
十一、当前官方建议带来的复核点
华为当前 CameraPicker FAQ 说明,系统相机页面由用户主动交互时,应用可不申请相机权限。也就是说,听见课堂现有的 CAMERA 运行时门禁可能比平台最小要求更严格。
这里不能直接宣布项目“错了”,因为还要核对目标 API、历史兼容、真机行为和上架材料;但可以明确列为技术债:评估移除门禁是否能减少一次不必要的拒绝路径。
十二、隐私文案必须和代码一致
设置页写着“仅在扫描页面由你点击后打开系统相机或选图页面”“无后台访问”。如果代码在启动时申请权限、后台访问相机或上传原图,这些文案就会失真。
当前调用由按钮触发,图片仅用于本机预览/OCR,保存时不写原图 URI。后续任何权限策略调整都要同步 manifest、原因字符串和隐私说明。
十三、拒绝后不要循环弹窗
DENIED 分支直接返回 false,避免一次按钮操作内反复申请。若用户选择“不再询问”,应用应通过明确管理入口引导系统设置,而不是每次进入 P05 都弹窗。
是否存在“可再次询问”与“永久拒绝”的更细状态,要以当前 SDK API 和真机返回为准,不能只从一个枚举值推断。
十四、模拟器证据说明了什么
既有复验在 HarmonyOS 模拟器上确认:系统相机不可用时页面可恢复,系统图库可打开并安全取消,本地示例到 P06 保存闭环通过。模拟器没有相机和真实图片,因此不能证明授权成功后的拍照与 OCR 成功。
这正说明降级设计有价值,但也提醒我们不要把“失败处理通过”写成“核心能力全通过”。
十五、验收矩阵
需要分别验证首次询问、允许、拒绝、再次点击、系统设置恢复、CameraPicker 无需权限的目标 SDK 行为、图库成功/取消、本地示例、OCR 失败人工录入,以及保存后数据库不包含 URI。
还要检查按钮禁用和 isScanProcessing,避免权限弹窗期间重复触发系统 UI。
十六、总结
权限设计的目标不是“拿到权限”,而是在最小授权下完成用户任务。听见课堂已经把图库、本地示例和人工复核做成可执行恢复路径;下一步应根据当前官方 CameraPicker 规范复核 CAMERA 门禁,减少不必要的权限摩擦。
下一篇将展开 PhotoViewPicker:为什么它可以让用户只授予某张图片,而不是开放整个媒体库。
参考:华为 CameraPicker 常见问题、应用隐私保护、项目 requestCameraPermission() 与 P05 页面。
更多推荐


所有评论(0)