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

结尾

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

相关推荐
行者-全栈开发10 小时前
【鸿蒙心迹】三方库移植(二)——CMake 交叉编译与符号冲突排查实录(HarmonyOS 7.x)
harmonyos·cmake·交叉编译·三方库移植·ohos·符号冲突
梦想不只是梦与想12 小时前
鸿蒙三方库源码调试
harmonyos·断点调试·三方源码调试
用户1179104883314 小时前
AI输出满屏井号星号?hmharness把Markdown渲染成终端表格 GitHub:swsgbl/hmharness
ai编程·harmonyos
了一12316 小时前
鸿蒙ArkWeb 长截图(滚动截图)技术方案总结
harmonyos
熊猫钓鱼>_>17 小时前
平行视界兼容模式与魔法变量配置避坑【鸿蒙心迹】
运维·服务器·开发语言·笔记·华为·harmonyos·openharmony
罗四强18 小时前
第2篇:环境搭建:DevEco Studio 安装 + 第一个 Hello World
harmonyos·鸿蒙·鸿蒙系统
用户1179104883319 小时前
AI终端里复制不了代码?hmharness把鼠标还给终端 GitHub:swsgbl/hmharness
ai编程·harmonyos
贾伟康21 小时前
HarmonyOS 端侧智能体长对话压缩:摘要版本、证据索引与安全回退
harmonyos·arkts·状态恢复·上下文压缩·端侧智能体
NJPJI_Yang1 天前
鸿蒙操作系统小艺 Skill 开发实战:让应用被 HarmonyOS 7 一句话召唤
pytorch·深度学习·harmonyos
redtank20001 天前
纯血鸿蒙学习效率三件套实测:背单词艾宾浩斯曲线、时间记录与睡眠辅助
学习·华为·harmonyos