这是一个典型的权限配置与审核环境差异导致的问题。错误码 13900020 通常与权限未授权或功能依赖的元能力(Ability)在审核环境中未被正确触发有关。
核心问题分析:
- 真机测试与审核环境差异:在您自己的真机上进行调试时,应用通常已被手动授予了所有相关权限(如相机
ohos.permission.CAMERA等),并且系统弹窗提示已被同意。然而,华为应用市场的审核环境是全新的、标准化的测试环境,所有权限默认处于未授予状态。
cardRecognition控件的权限依赖:身份证识别功能强依赖于相机权限。此外,该功能本身属于敏感功能,其调用可能受到系统隐私管控策略的约束。
- 错误码13900020:此错误码表明卡证识别服务调用失败,根本原因通常是前置条件不满足,最常见的就是必需的权限未被授予。
解决方案:
请按以下步骤检查和修改您的应用配置:
1. 在module.json5配置文件中明确定义所有必需的权限。
在您的应用模块的module.json5文件中,确保已声明相机权限。这是最基本且必须的一步。
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.CAMERA",
"reason": "$string:camera_permission_reason", // 可选,但建议提供理由字符串
"usedScene": {
"abilities": [
"您的Ability名称" // 使用此权限的Ability,例如EntryAbility
],
"when": "always"
}
}
]
}
}
2. 在调用cardRecognition前,进行动态权限检查与申请。
不能假设权限已被授予。必须在业务代码中,在触发识别操作之前,显式地检查并申请权限。
import { cardRecognition } from '@kit.ConnectivityKit';
import { common, wantAgent } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { abilityAccessCtrl, Permissions } from '@kit.AbilityKit';
// 1. 定义需要申请的权限列表
const PERMISSIONS: Array<Permissions> = ['ohos.permission.CAMERA'];
// 2. 权限检查与申请函数
async function checkAndRequestPermissions(): Promise<void> {
let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
// 检查权限状态
let grantStatus: abilityAccessCtrl.GrantStatus = await atManager.checkAccessToken(
context.tokenId,
PERMISSIONS[0]
);
if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
// 权限已授予,可以执行识别操作
startCardRecognition();
} else {
// 权限未授予,发起授权请求
console.info('Requesting CAMERA permission...');
atManager.requestPermissionsFromUser(context, PERMISSIONS).then((data) => {
if (data.authResults[0] === 0) {
// 用户授权成功
startCardRecognition();
} else {
// 用户拒绝授权,需要给出友好提示,引导用户去设置中开启
console.error('User denied the CAMERA permission.');
// 此处应提示用户“身份证识别需要相机权限,请到应用设置中开启”
}
}).catch((err: BusinessError) => {
console.error(`Failed to request permissions. Code: ${err.code}, message: ${err.message}`);
});
}
}
// 3. 您的身份证识别函数
async function startCardRecognition() {
// 确保在权限确认后,再调用cardRecognition.start()
try {
let result = await cardRecognition.start();
// 处理识别结果...
} catch (error) {
// 处理错误,包括13900020
console.error(`Card recognition failed. Code: ${error.code}, message: ${error.message}`);
}
}
// 在您的按钮点击或触发识别的地方,调用权限检查函数
// 例如:onClick() { checkAndRequestPermissions(); }
3. 确保用户界面(UI)有明确的触发点。
审核人员需要看到一个明确的UI元素(如按钮)来触发身份证识别功能,并且该触发操作应能正常拉起系统的权限申请弹窗。避免在应用启动或页面加载时自动调用识别功能。
4. 检查cardRecognition的调用时机。
确保cardRecognition.start()方法是在一个明确的用户交互事件(如按钮onClick)回调中,并且在权限确认已被授予之后调用。不要在onPageShow等生命周期中自动调用,这可能导致在审核环境中因权限弹窗未及时响应而失败。
总结:
问题根源在于审核环境中权限未被默认授予。请务必在代码中加入动态权限申请逻辑,并在module.json5中正确声明权限。确保审核人员能够通过一个清晰的UI操作,触发权限申请流程,并在授权后正常使用识别功能。