【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();
  })

结尾

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

相关推荐
天夏已微凉3 小时前
OpenHarmony系统HDF驱动开发介绍(补充)
驱动开发·音视频·harmonyos
特立独行的猫a9 小时前
HarmonyOS 【诗韵悠然】AI古诗词赏析APP开发实战从零到一系列(一、开篇,项目介绍)
人工智能·华为·harmonyos·古诗词
幽蓝计划13 小时前
鸿蒙跨平台开发教程之Uniapp布局基础
harmonyos
周胡杰14 小时前
鸿蒙接入flutter环境变量配置windows-命令行或者手动配置-到项目的创建-运行demo项目
javascript·windows·flutter·华为·harmonyos·鸿蒙·鸿蒙系统
半青年15 小时前
华为鸿蒙电脑能否作为开发机?开发非鸿蒙应用?
ide·华为·编辑器·电脑·idea·harmonyos·visual studio
高心星15 小时前
鸿蒙5.0项目开发——鸿蒙天气项目的实现(介绍)
arkts·arkui·鸿蒙项目·harmonyos5.0·鸿蒙天气
bestadc18 小时前
鸿蒙 核心与非核心装饰器
harmonyos
@兔然暴富@19 小时前
#跟着若城学鸿蒙# HarmonyOS NEXT学习之AlphabetIndexer组件详解
harmonyos
沙振宇21 小时前
【HarmonyOS】ArkTS开发应用的横竖屏切换
android·华为·harmonyos
bestadc1 天前
鸿蒙 从打开一个新窗口到Stage模型的UIAbility组件
harmonyos