【HarmonyOS】关于鸿蒙原生使用原生相机实现扫一扫功能

开发语言:ArkTs

开发工具:DevEco Studio 5.0.0 Release

API版本:API 12

demo演示Gitee:harmony-qrscan.git

需求:扫描二维码或条形码识别结果

一、打开相机权限

1、在module.json5文件中配置相机权限
ts 复制代码
"requestPermissions": [
  {
    "name": 'ohos.permission.CAMERA',
    "reason": "$string:permission_camera_reason",
    "usedScene": {
      "when": "inuse"
    }
  }
]
2、请求相机权限
ts 复制代码
/**
 * 请求权限
 * @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、检查相机权限
ts 复制代码
/**
 * 检测是否申请权限
 * @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、初始化扫一扫
ts 复制代码
// 初始化相机
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、启动相机
ts 复制代码
// 启动相机
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、关闭和释放相机
ts 复制代码
// 关闭相机
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、打开或关闭闪光灯
ts 复制代码
// 打开或关闭闪光灯
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));
  }
}

三、扫一扫组件

ts 复制代码
// 数据流控制器
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();
  })

结尾

如大家发现文章描述有问题或有更好的方案,还请评论回复,一起探讨学习,感谢!

相关推荐
别说我什么都不会1 小时前
当OpenHarmony遇上OpenEuler
操作系统·嵌入式·harmonyos
没有了遇见1 小时前
鸿蒙学习ArkTS之工程目录说
harmonyos
没有了遇见1 小时前
鸿蒙学习ArkTS之Module创建和引用
harmonyos
万少2 小时前
喜大普奔 DevEco Studio 官方接 入 DeepSeek 了
人工智能·harmonyos·ai 编程
遇到困难睡大觉哈哈3 小时前
HarmonyOS 音频录制与播放模块
华为·音视频·harmonyos·鸿蒙
IT乐手4 小时前
2.2、层叠布局(Stack)
harmonyos
IT乐手4 小时前
2.1、线性布局(Row/Column)
harmonyos
Georgewu5 小时前
【HarmonyOS Next】鸿蒙加固方案调研和分析
前端·面试·harmonyos
月未央5 小时前
HarmonyOS Next 开发系列:Provider和Consumer状态修饰器实践
ios·harmonyos
全栈若城5 小时前
16 HarmonyOS NEXT UVList组件开发指南(三)
harmonyos