写点什么

【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
用户头像

还未添加个人签名 2025-03-18 加入

还未添加个人简介

评论

发布
暂无评论
【HarmonyOS】关于鸿蒙原生使用原生相机实现扫一扫功能_鸿蒙_走向菜鸟的菜鸟_InfoQ写作社区