【HarmonyOS】关于鸿蒙原生实现扫一扫功能

开发语言: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();
  })

结尾

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值