HarmonyOS 鸿蒙Next 调用自定义扫码组件扫码时,扫码页面未正常拉起如何解决
HarmonyOS 鸿蒙Next 调用自定义扫码组件扫码时,扫码页面未正常拉起如何解决
【问题现象】
项目中使用customScan自定义扫码组件,调试时扫码页面未正常拉起。
预期效果:成功获取到相机资源,显示扫码界面。
实际效果:扫码界面没成功拉起,界面显示异常,如下图。
问题代码如下:
// 设置预览流高度,默认单位:vp
[@State](/user/State) cameraHeight: number = 2720
// 设置预览流宽度,默认单位:vp
[@State](/user/State) cameraWidth: number = 1260
...
scanInitAndStart() {
...
this.mXComponentController.setXComponentSurfaceSize({
surfaceWidth: this.cameraWidth, // 使用预览流宽度
surfaceHeight: this.cameraHeight // 使用预览流高度
})
let surfaceId: string = this.mXComponentController.getXComponentSurfaceId();
hilog.info(0x0001, 'viewControl', `onLoad surfaceId: ${surfaceId}`);
// 设置ViewControl相应字段
let viewControl: customScan.ViewControl = {
width: this.cameraWidth,
height: this.cameraHeight,
surfaceId: surfaceId
};
...
}
【背景知识】
自定义界面扫码能力提供了相机流控制接口,可根据自身需求自定义扫码界面,适用于对扫码界面有定制化需求的应用开发。
【定位思路】
自定义扫码组件正常生效的关键是能够获取相机资源,并按正确比例渲染,因此可以从相机权限和分辨率比例方面进行排查:
- 编码时是否添加申请相机权限的声明;
- XComponent组件与相机分辨率比例是否偏差太大;
- 拉起扫码时需要动态申请相机权限,用户是否授权。
【解决方案】
详细的排查步骤如下:
1、检查是否配置权限申请
查看模块配置文件module.json5中是否添加camera权限声明。若未配置,则需要在其中添加声明,如下:
"requestPermissions": [
{
"name": "ohos.permission.CAMERA",
"reason": "$string:reason",
"usedScene": {
"abilities": [
"FormAbility"
],
"when": "inuse"
}
}
]
2、检查viewcontrol的宽高是否适配相机最优分辨率
viewcontrol宽高需要与XComponent相同,且比例不能与相机分辨率相差很大。若不同,则可能会出现扫码画面拉伸、黑屏等异常现象。典型错误码如“内部错误”。由于在不同手机、Pad以及折叠屏的不同状态下,viewcontrol的宽高比会不同,相差过大有可能会导致功能异常,当前支持的分辨率比例为16:9、4:3、1:1。通常情况下,建议使用16:9的宽高比,该比例符合大多数设备的分辨率比例,使用更广泛。
排查发现问题代码使用的宽高比近似2:1,因此考虑重新修改宽高比为16:9:
...
setDisplay() {
try {
let displayClass = display.getDefaultDisplaySync();
this.displayHeight = px2vp(displayClass.height);
this.displayWidth = px2vp(displayClass.width);
let maxLen: number = Math.max(this.displayWidth, this.displayHeight);
let minLen: number = Math.min(this.displayWidth, this.displayHeight);
const RATIO: number = 16 / 9; //设置宽高比例
this.cameraHeight = maxLen;
this.cameraWidth = maxLen / RATIO;
this.offsetX = (minLen - this.cameraWidth) / 2;
} catch (error) {
hilog.error(0x0001, TAG, `Failed to getDefaultDisplaySync. Code: ${error.code}, message: ${error.message}`);
}
}
...
3、确认用户授权
拉起自定义扫码界面时需要动态申请相机的权限。扫码过程中,需要等待用户授权后,才能启动相机流进行扫码。
经过以上排查,发现是viewcontrol的宽高比与相机分辨率不匹配导致的问题,修改后正常拉起扫码页面效果如下图:
【总结】
自定义的扫码组件和系统自带的扫码组件在不同的使用场景各有优势,根据具体的使用场景,可以灵活的选择使用哪种实现: