华为统一扫码服务(Scan Kit)
简介
华为统一扫码服务(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
对象;将图像信息转换为
MLFrame
,MLFrame
为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)相关推荐
- Android扫码功能--华为统一扫码服务
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.华为统一扫码服务是什么? 二.使用步骤 1.准备工作 2.开启扫码功能 3.自定义扫码页面 4.同时识别多个二维码 ...
- Android 扫描二维码(使用华为统一扫码服务 + 附源码)
前言 现在无论什么APP都会有一个扫一扫的功能,网络上的各个软件的扫码功能也都大同小异,当然你想要自定义属于自己APP的扫码界面及功能的话,还是要花一番功夫的,不过做Demo,用第三方的就可以了. ...
- 别再问WiFi密码了,HMS Core统一扫码服务让手机一键联网
现代生活离不开网络,在餐厅.商场等公共场所,手机连接WiFi一直是高频使用场景.虽然公共场所的免费WiFi越来越多,但网络连接过程却很麻烦.有的需要打开网页注册或点击广告链接才能上网,还有的要求下载特 ...
- 驾考宝典携手HMS Core统一扫码服务,构建复杂场景中的流畅扫码体验
"驾考宝典"是一款颇具人气的互联网综合驾照考试学习应用,通过强大的驾考功能,在手机移动端为学车学员提供从报名.学习到拿本的全方位驾考服务.作为一个专业的驾培平台,"驾考宝 ...
- 携手HMS Core统一扫码服务, 兴业证券优理宝App提升用户扫码体验
兴业证券优理宝App联合华为HMS Core,集成HMS Core统一扫码服务,在提升扫码成功率的同时,还支持C端用户用手机端APP扫描手表端二维码,实现行情在手机与手表间跨终端流转,行情信息,抬腕可 ...
- 【HMS Core】统一扫码服务中的RemoteView如何修改视图比例?
1.问题描述 项目中有一个需求:将扫码视图设置为正方形. 详情如下图所示: 目前默认的视图是按屏幕比例展示的,将视图设置为正方形时,视图的Y轴将会被压缩,现在的问题是: 该View是否支持自定义比例展 ...
- Android 扫描二维码(Scan Kit)
Android 扫描二维码(Scan Kit) 华为统一扫码服务(Scan Kit)能够提供专业的二维码与条形码扫描与解析能力,通过集成Scan Kit,帮助应用快速构建扫码功能. 统一扫码服务的功能 ...
- 扫码支付java,详解JAVA后端实现统一扫码支付:微信篇
最近做完了一个项目,正好没事做,产品经理就给我安排了一个任务. 做一个像收钱吧这样可以统一扫码收钱的功能. 一开始并不知道是怎么实现的,咨询了好几个朋友,才知道大概的业务流程:先是开一个网页用来判断支 ...
- 如何用Java微信扫码实现签到_详解JAVA后端实现统一扫码支付:微信篇
最近做完了一个项目,正好没事做,产品经理就给我安排了一个任务. 做一个像收钱吧这样可以统一扫码收钱的功能. 一开始并不知道是怎么实现的,咨询了好几个朋友,才知道大概的业务流程:先是开一个网页用来判断支 ...
最新文章
- 我进公司当Android开发实习生时,初中最差的同学成了我的领导
- 【R】神经网络相关的R包
- node 多进程 vs java_node多进程服务器
- android shell hello world,Android Framework 之HelloWorld(三)
- 检测和测试停滞的流– RxJava常见问题解答
- Linux集群架构(LVS DR模式搭建、keepalived + LVS)
- C++ 函数的引用传递
- 【leetcode】41. First Missing Positive
- 蝴蝶优化算法_腾讯机智团队分享--AllReduce算法的前世今生
- 为什么一个程序中变量只能定义一次_#带你学Python# 从简单程序出发理解Python基本语法
- malloc/free 与 new/delete的区别
- python 选择多个文件_python-PyQt QFileDialog-多目录选择
- installshield使用教程
- 除了巨沃、富勒WMS,还有什么更好用的仓库管理系统?
- 带通滤波器的设计概述
- 英语16种时态表和人称表
- 「 ROS 」Gazebo仿真平台中机器人添加运动关节(旋转副)讲解
- 彻底解决unable to find valid certification path to requested target
- Scratch滚动的天空(3)
- linux的下载利器——aira2 可以下载磁力链接