【HarmonyOS】关于鸿蒙原生使用原生相机实现扫一扫功能
作者:走向菜鸟的菜鸟
- 2025-03-21 安徽
本文字数:2434 字
阅读完需:约 8 分钟
开发语言:ArkTs
开发工具:DevEco Studio 5.0.0 Release
API 版本:API 12
demo 演示Gitee:harmony-qrscan.git
需求:扫描二维码或条形码识别结果
一、打开相机权限
1、在module.json5文件中配置相机权限
"requestPermissions": [ { "name": 'ohos.permission.CAMERA', "reason": "$string:permission_camera_reason", "usedScene": { "when": "inuse" } }]
复制代码
2、请求相机权限
/** * 请求权限 * @param type 权限类型 */static async requestSystemAuth(type: SystemAuthType): Promise<boolean> { // 权限管理 let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); let context = getContext() as common.UIAbilityContext;
let permissionArr: Permissions[] = ['ohos.permission.CAMERA'] let isGrant: boolean = false; await atManager.requestPermissionsFromUser(context, permissionArr).then((data) => { let grantStatus: number[] = data.authResults; let length: number = grantStatus.length; for (let i = 0; i < length; i++) { if (grantStatus[i] === 0) { // 用户授权 isGrant = true; } else { // 用户拒绝 isGrant = false; } } }).catch((err: BusinessError) => { console.error('HMSystemAuthManager', 'Failed to request permissions from user. Code is ' + err.code + ', message is ' + err.message) }) return isGrant;}
复制代码
3、检查相机权限
/** * 检测是否申请权限 * @param permission 权限 * @returns true 权限状态 */static async checkPermission(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> { let atManager = abilityAccessCtrl.createAtManager(); let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;
// 获取应用accessTokenID let tokenId: number = -10; try { let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION); let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo; tokenId = appInfo.accessTokenId; } catch (err) { console.error('YTPermissionCheck', `getBundleInfoForSelf failed, code is ${err.code}, message is ${err.message}`); }
// 校验应用是否被授予权限 try { grantStatus = await atManager.checkAccessToken(tokenId, permission); } catch (err) { console.error('PermissionCheck', `checkAccessToken failed, code is ${err.code}, message is ${err.message}`); }
return grantStatus;}
复制代码
二、扫一扫功能
1、初始化扫一扫
// 初始化相机initCamera() { // 用户已授权,开始初始化 let options: scanBarcode.ScanOptions = { scanTypes: [scanCore.ScanType.ALL], enableMultiMode: true, enableAlbum: true } // 默认竖屏 this.cameraHeight = 800 this.cameraWidth = 450 try { customScan.init(options); } catch (error) { console.debug('camera failed to init, error ', JSON.stringify(error)); }}
复制代码
2、启动相机
// 启动相机startCamera() { // 获取 this.surfaceId = this.mXComponentController.getXComponentSurfaceId(); let viewControl: customScan.ViewControl = { width: this.cameraWidth, height: this.cameraHeight, surfaceId: this.surfaceId };
try { customScan.start(viewControl).then((result: Array<scanBarcode.ScanResult>) => { // 处理扫码结果 this.showScanResult(result); }) } catch (error) { console.debug('camera failed to start, error ', JSON.stringify(error)); }}
// 处理扫描结果showScanResult(result: Array<scanBarcode.ScanResult>) { if (result.length > 0) { // 获取到扫描结果后暂停相机流 this.closeCamera() // 处理扫码结果 let resultStr: string = result[0].originalValue; }}
复制代码
3、关闭和释放相机
// 关闭相机closeCamera() { try { customScan.stop(); } catch (error) { console.debug('camera failed to stop, error ', JSON.stringify(error)); }}
// 释放相机releaseCamera() { try { customScan.release() } catch (error) { console.debug('camera failed to release, error ', JSON.stringify(error)); }}
复制代码
4、打开或关闭闪光灯
// 打开或关闭闪光灯openOrCloseFlashlight() { try { if (this.flashStatus) { customScan.closeFlashLight(); this.flashStatus = false; } else { customScan.openFlashLight(); this.flashStatus = true; } } catch (error) { console.debug('camera failed to flashLight, error ', JSON.stringify(error)); }}
复制代码
三、扫一扫组件
// 数据流控制器private mXComponentController: XComponentController = new XComponentController();
// 扫码区域XComponent({ id: 'componentId', type: 'surface', controller: this.mXComponentController}) .onLoad(()=>{ // 加载时开始扫描 this.flashStatus = false; this.initCamera(); this.startCamera(); }) .onDestroy(()=>{ // 组件释放时释放相机(不能使用stop停止相机,会一直黑屏) this.flashStatus = true; this.openOrCloseFlashlight(); this.releaseCamera(); })
复制代码
结尾
如大家发现文章描述有问题或有更好的方案,还请评论回复,一起探讨学习,感谢!
划线
评论
复制
发布于: 刚刚阅读数: 4
版权声明: 本文为 InfoQ 作者【走向菜鸟的菜鸟】的原创文章。
原文链接:【http://xie.infoq.cn/article/99ef60c8950391682b5d4ec8b】。文章转载请联系作者。
走向菜鸟的菜鸟
关注
还未添加个人签名 2025-03-18 加入
还未添加个人简介









评论