简介

华为统一扫码服务(Scan Kit)提供便捷的条形码和二维码扫描、解析、生成能力,帮助开发者快速构建应用内的扫码功能。

得益于华为在计算机视觉领域能力的积累,Scan Kit 可以实现远距离码或小型码的检测和自动放大,同时针对常见复杂扫码场景(如反光、暗光、污损、模糊、柱面)做了针对性识别优化,提升扫码成功率与用户体验。

Scan Kit 支持 Android 和 iOS 系统集成。其中,Android 系统集成 Scan Kit 后支持横屏扫码能力。

支持的设备

平台 设备类型 OS版本
Android 华为手机、华为平板 EMUI 3.1以上
Android 非华为手机 Android 4.4及以上
iOS 手机 iOS 9.0以上

场景介绍

扫码

Scan Kit 支持扫描13种全球主流的码制式。如果开发者的应用只处理部分特定的码制式,开发者也可以在接口中指定制式以便加快扫码速度。已支持的码制式:

  • 一维码:EAN-8、EAN-13、UPC-A、UPC-E、Codabar、Code 39、Code 93、Code 128、ITF-14

  • 二维码:QR Code、Data Matrix、PDF417、Aztec

Scan Kit 提供多种调用模式,开发者可根据需求选择一个合适的模式构建扫码功能。

调用方式 支持平台 扫码流程 扫码界面 功能
Default View Mode Android/iOS Scan Kit处理 Scan Kit提供 相机扫码(可以调用Bitmap mode增加导入图片扫码功能)。
Customized View Mode Android/iOS Scan Kit处理 开发者自定义 相机扫码(可以叠加Bitmap mode增加导入图片扫码功能)。
Bitmap Mode Android/iOS 开发者应用处理 开发者自定义 相机扫码、导入图片扫码。
MultiProcessor Mode Android 开发者应用处理 开发者自定义 相机扫码、导入图片扫码,支持同时检测多个码。
  • 对于希望快速构建强大扫码功能的开发者,建议选择 Default View Mode 或者 Customized View Mode。在这两种模式下,Scan Kit 直接控制相机实现最优的相机 Zoom 控制、自适应的曝光调节、自适应对焦调节等操作,保障最佳的扫码体验,减少开发者的工作量。Default View Mode 和 Customized View Mode 的区别在于后者支持开发者自定义扫码界面 UI。

  • 对于希望完全自定义扫码流程并自行控制相机的开发者,可以选择 Bitmap Mode 构建扫码功能。Bitmap Mode 需要开发者自行控制相机,且提供相机扫码和导入图片扫码两种模式,在调用扫码接口时设置。当用户在扫描较小或者较远的二维码时,Scan Kit 会返回需要放大的倍数给您的应用,开发者只需按照返回值调整相机焦距就能快速获取满足条件的图片。请注意,Scan Kit 返回的放大倍数是通过检测结果和用户场景计算得出,建议开发者不要更改此放大倍数,否则可能会降低实际使用效果。

  • MultiProcessor Mode 适用于需要同时扫描多个码的场景。因为 MultiProcessor 处理效率低于其他三种调用方式,如果没有上述需求,建议使用其他三种调用方式。MultiProcessor Mode 提供同步和异步两种模式,可以根据实际需求选择一个合适的模式。

码值解析

Scan Kit可以将码的原始内容返回给开发者,还会针对使用特定内容格式编码的二维码/条形码进行分析并提取结构化数据,帮助开发者快速构建关联服务。已支持如下场景:联系人信息Wi-Fi 连接信息网页日历日程ID 卡短信电话邮件地理位置商品条码ISBN

码生成

Scan Kit 支持将字符串转换为一维码或二维码,目前已支持的码制式为EAN-8、EAN-13、UPC-A、UPC-E、Codabar、Code 39、Code 93、Code 128、ITF-14、QR Code、Data Matrix、PDF417、Aztec。开发者只需要提供字符串、码制式和尺寸要求即可获得相应的码图。

集成步骤

官方教程中【配置AppGallery Connect】步骤,如果应用无上架需求,可以忽略。

集成HMS Core SDK

配置HMS Core SDK的Maven仓地址

打开Android Studio项目级 build.gradle 文件

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {ext.kotlin_version = "1.5.0"repositories {google()jcenter()// 配置HMS Core SDK的Maven仓地址。maven {url 'https://developer.huawei.com/repo/'}}dependencies {classpath "com.android.tools.build:gradle:4.2.1"classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"}
}allprojects {repositories {google()jcenter() // 配置HMS Core SDK的Maven仓地址。maven {url 'https://developer.huawei.com/repo/'}}
}

添加编译依赖

打开应用级的 build.gradle 文件,添加对应的编译依赖。华为官方给我们提供了两种类型的依赖包:

SDK

区别比较明显,包的大小和识别能力两个方面的影响,这里为了展示 Scan Kit 的能力,我们选用能力更全面的 scanplus 系列。

implementation 'com.huawei.hms:scanplus:1.3.2.300'

应用开发

动态权限请求处理,不单独介绍,穿插于代码中,重点介绍下 Scan Kit 的四种模式:

  • Default View Mode

  • Customized View Mode

  • Bitmap Mode

  • MultiProcessor Mode

Default View Mode

Default View Mode 提供相机扫码和导入图片扫码两个功能,提供完整的 Activity ,不需要开发者开发扫码界面的 UI 。一键开启扫码,处理扫码结果即可,非常适合定制化要求不高的一般扫码场景。主要步骤:

  • 创建扫码选项参数;

  • 启动扫码;

  • 实现回调接口接收扫码结果。

fun startDefaultMode(view: View) {// 扫码选项参数val options =HmsScanAnalyzerOptions.Creator().setHmsScanTypes(HmsScan.ALL_SCAN_TYPE).create()ScanUtil.startScan(this, REQUEST_CODE_SCAN_DEFAULT_MODE,options)
}override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)if (resultCode != RESULT_OK || data == null) {return}when (requestCode) {REQUEST_CODE_SCAN_DEFAULT_MODE -> {val hmsScan: HmsScan? = data.getParcelableExtra(ScanUtil.RESULT) // 获取扫码结果 ScanUtil.RESULTif (!TextUtils.isEmpty(hmsScan?.getOriginalValue())) {mBinding.tvResult.text = hmsScan?.getOriginalValue()}}……}
}

Customized View Mode

Customized View 支持开发者自定义扫码界面,扫码过程和相机控制将由 Scan Kit 完成。这种模式更适合对扫码界面有定制化要求的场景,借助 Scan Kit 的扫码能力完成 UI 定制化需求。主要步骤:

  • 自定义扫码页面元素;

  • 通过 Customized View 实现相机扫码功能【详细步骤请看注释】。

class CustomizedModeActivity : AppCompatActivity() {companion object {const val SCAN_RESULT = "scanResult"private const val SCAN_FRAME_SIZE = 300}private var remoteView: RemoteView? = nullvar mScreenWidth = 0var mScreenHeight = 0private val mBinding by lazy {ActivityCustomizedModeBinding.inflate(layoutInflater)}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(mBinding.root)// 1. 获取屏幕密度计算 viewfinder 的矩形val dm = resources.displayMetrics// 2. 获取屏幕尺寸val density = dm.densitymScreenWidth = dm.widthPixelsmScreenHeight = dm.heightPixelsval scanFrameSize = (SCAN_FRAME_SIZE * density)// 3. 计算 viewinder 的矩形,放在布局中央val rect = Rect()apply {rect.left = (mScreenWidth / 2 - scanFrameSize / 2).toInt()rect.right = (mScreenWidth / 2 + scanFrameSize / 2).toInt()rect.top = (mScreenHeight / 2 - scanFrameSize / 2).toInt()rect.bottom = (mScreenHeight / 2 + scanFrameSize / 2).toInt()}// 4. 初始化RemoteView, 并且设置回调监听,这里可能设置扫码选项remoteView = RemoteView.Builder().setContext(this).setBoundingBox(rect).setFormat(HmsScan.ALL_SCAN_TYPE).build()remoteView?.onCreate(savedInstanceState)remoteView?.setOnResultCallback { result ->if (result != null && result.isNotEmpty() && result[0] != null && !TextUtils.isEmpty(result[0].getOriginalValue())) {val intent = Intent()intent.apply {putExtra(SCAN_RESULT, result[0])}setResult(Activity.RESULT_OK, intent)this.finish()}}// 5. 添加 RemoteView 至布局.val params = FrameLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT)mBinding.rim1.addView(remoteView, params)}// 6. 管理RemoteView 的生命周期override fun onStart() {super.onStart()remoteView?.onStart()}override fun onResume() {super.onResume()remoteView?.onResume()}override fun onPause() {super.onPause()remoteView?.onPause()}override fun onDestroy() {super.onDestroy()remoteView?.onDestroy()}override fun onStop() {super.onStop()remoteView?.onStop()}
}

Bitmap Mode

顾名思义,此模式下的识别对象是 Bitmap ,不管这个 Bitmap 从何而来。前面两种模式,我们只需要关系 UI 界面和扫码选项,而 Bitmap 模式更加灵活,你可以通过相机取帧的方式生成 Bitmap 进行检测,也可以通过图片文件转换成 Bitmap 进行检测等等,能 Bitmap 就能 检测,适用于图片识码等场景。主要步骤:

  • 将数据转成 Bitmap (相机数据、文件等);

  • 初始化HmsScanAnalyzerOptions,设置支持识别的码制式和设置 Bitmap 模式为图片扫码模式;

  • 调用 ScanUtil的静态方法decodeWithBitmap发起扫码请求并获取扫码结果对象HmsScan 。

fun startBitmapMode(view: View) {EasyPhotos.createAlbum(this, false, false,GlideEngine.getInstance()).setFileProviderAuthority(BuildConfig.APPLICATION_ID).setCount(1).start(object : SelectCallback() {override fun onResult(photos: ArrayList<Photo>?, isOriginal: Boolean) {photos?.let {val path = photos.first().pathif (TextUtils.isEmpty(path)) {return}// 1. 转换为 Bitmapval bitmap = ScanUtil.compressBitmap(this@MainActivity, path)// 2. 调用 decodeWithBitmap 方法识别 Bitmap.val result = ScanUtil.decodeWithBitmap(this@MainActivity,bitmap,HmsScanAnalyzerOptions.Creator().setHmsScanTypes(0).setPhotoMode(false).create())// 3. 显示识别结果if (result != null && result.isNotEmpty()) {if (!TextUtils.isEmpty(result[0].getOriginalValue())) {mBinding.tvResult.text = result[0].getOriginalValue()}}}}override fun onCancel() {Toast.makeText(this@MainActivity,"图片选取失败",Toast.LENGTH_SHORT).show()}})
}

MultiProcessor Mode

相机扫码、导入图片扫码,支持同时检测多个码,支持同步异步两种方式。这种模式是 Bitmap Mode 的延续,该模式下使用的 MLFrame需要使用 Bitmap 生成,当然我们也有其他方式生成MLFrame,但是 Bitmap 居多。主要步骤:

  • 将数据转成 Bitmap (相机数据、文件等);

  • 初始化HmsScanAnalyzerOptions并设置支持识别的码制式;

  • 初始化HmsScanAnalyzer对象;

  • 将图像信息转换为MLFrameMLFrame为ML Kit封装的图像信息类;

  • 调用HmsScanAnalyzer对象的analyseFrame扫码方法发起扫码请求并获取扫码结果。

 fun startMultiProcessorMode(view: View) {EasyPhotos.createAlbum(this, false, false,GlideEngine.getInstance()).setFileProviderAuthority(BuildConfig.APPLICATION_ID).setCount(1).start(object : SelectCallback() {override fun onResult(photos: ArrayList<Photo>?, isOriginal: Boolean) {photos?.let {val path = photos.first().pathif (TextUtils.isEmpty(path)) {return}// 1. 转换为 Bitmapval bitmap = ScanUtil.compressBitmap(this@MainActivity, path)// 2. 配置可选项val options =HmsScanAnalyzerOptions.Creator().setHmsScanTypes(HmsScan.ALL_SCAN_TYPE).create()// 3. 初始化 HmsScanAnalyzer 对象val scanAnalyzer = HmsScanAnalyzer(options)// 4. 构建 MLFrameval image = MLFrame.fromBitmap(bitmap)// 5. 扫码识别/*  同步模式                      val result: SparseArray<HmsScan> = scanAnalyzer.analyseFrame(image)Log.d(TAG, result.toString())*/// 异步模式scanAnalyzer.analyzInAsyn(image).addOnSuccessListener {if (it != null && it.size > 0) {var resultStr = ""it.forEach { value ->resultStr = resultStr.plus(value.originalValue).plus("\n")}mBinding.tvResult.text = resultStr}}.addOnFailureListener {it?.printStackTrace()Log.d(TAG, it.message ?: "")}}}override fun onCancel() {Toast.makeText(this@MainActivity,"图片选取失败",Toast.LENGTH_SHORT).show()}})}

效果

源码

https://github.com/onlyloveyd/ScanKitSample

华为统一扫码服务(Scan Kit)相关推荐

  1. Android扫码功能--华为统一扫码服务

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.华为统一扫码服务是什么? 二.使用步骤 1.准备工作 2.开启扫码功能 3.自定义扫码页面 4.同时识别多个二维码 ...

  2. Android 扫描二维码(使用华为统一扫码服务 + 附源码)

    前言   现在无论什么APP都会有一个扫一扫的功能,网络上的各个软件的扫码功能也都大同小异,当然你想要自定义属于自己APP的扫码界面及功能的话,还是要花一番功夫的,不过做Demo,用第三方的就可以了. ...

  3. 别再问WiFi密码了,HMS Core统一扫码服务让手机一键联网

    现代生活离不开网络,在餐厅.商场等公共场所,手机连接WiFi一直是高频使用场景.虽然公共场所的免费WiFi越来越多,但网络连接过程却很麻烦.有的需要打开网页注册或点击广告链接才能上网,还有的要求下载特 ...

  4. 驾考宝典携手HMS Core统一扫码服务,构建复杂场景中的流畅扫码体验

    "驾考宝典"是一款颇具人气的互联网综合驾照考试学习应用,通过强大的驾考功能,在手机移动端为学车学员提供从报名.学习到拿本的全方位驾考服务.作为一个专业的驾培平台,"驾考宝 ...

  5. 携手HMS Core统一扫码服务, 兴业证券优理宝App提升用户扫码体验

    兴业证券优理宝App联合华为HMS Core,集成HMS Core统一扫码服务,在提升扫码成功率的同时,还支持C端用户用手机端APP扫描手表端二维码,实现行情在手机与手表间跨终端流转,行情信息,抬腕可 ...

  6. 【HMS Core】统一扫码服务中的RemoteView如何修改视图比例?

    1.问题描述 项目中有一个需求:将扫码视图设置为正方形. 详情如下图所示: 目前默认的视图是按屏幕比例展示的,将视图设置为正方形时,视图的Y轴将会被压缩,现在的问题是: 该View是否支持自定义比例展 ...

  7. Android 扫描二维码(Scan Kit)

    Android 扫描二维码(Scan Kit) 华为统一扫码服务(Scan Kit)能够提供专业的二维码与条形码扫描与解析能力,通过集成Scan Kit,帮助应用快速构建扫码功能. 统一扫码服务的功能 ...

  8. 扫码支付java,详解JAVA后端实现统一扫码支付:微信篇

    最近做完了一个项目,正好没事做,产品经理就给我安排了一个任务. 做一个像收钱吧这样可以统一扫码收钱的功能. 一开始并不知道是怎么实现的,咨询了好几个朋友,才知道大概的业务流程:先是开一个网页用来判断支 ...

  9. 如何用Java微信扫码实现签到_详解JAVA后端实现统一扫码支付:微信篇

    最近做完了一个项目,正好没事做,产品经理就给我安排了一个任务. 做一个像收钱吧这样可以统一扫码收钱的功能. 一开始并不知道是怎么实现的,咨询了好几个朋友,才知道大概的业务流程:先是开一个网页用来判断支 ...

最新文章

  1. 我进公司当Android开发实习生时,初中最差的同学成了我的领导
  2. 【R】神经网络相关的R包
  3. node 多进程 vs java_node多进程服务器
  4. android shell hello world,Android Framework 之HelloWorld(三)
  5. 检测和测试停滞的流– RxJava常见问题解答
  6. Linux集群架构(LVS DR模式搭建、keepalived + LVS)
  7. C++ 函数的引用传递
  8. 【leetcode】41. First Missing Positive
  9. 蝴蝶优化算法_腾讯机智团队分享--AllReduce算法的前世今生
  10. 为什么一个程序中变量只能定义一次_#带你学Python# 从简单程序出发理解Python基本语法
  11. malloc/free 与 new/delete的区别
  12. python 选择多个文件_python-PyQt QFileDialog-多目录选择
  13. installshield使用教程
  14. 除了巨沃、富勒WMS,还有什么更好用的仓库管理系统?
  15. 带通滤波器的设计概述
  16. 英语16种时态表和人称表
  17. 「 ROS 」Gazebo仿真平台中机器人添加运动关节(旋转副)讲解
  18. 彻底解决unable to find valid certification path to requested target
  19. Scratch滚动的天空(3)
  20. linux的下载利器——aira2 可以下载磁力链接

热门文章

  1. uniapp真机 document.getElementById报错
  2. ts学习笔记 -- 基础类型
  3. 如何选择Web APP与Native App原生开发模式的区别
  4. docker容器内无法删除文件
  5. senior developer in Hongkong
  6. Linux系统空间满了怎么办
  7. 我的Java后端书架2016年暮春3.0版(转)
  8. windows环境安装adb驱动
  9. 【学神】 1-9 硬盘分区及挂载
  10. 我的世界如何快速制作 服务器,《我的世界》颜色代码快速指南