Android开发笔记(一百八十三)利用HMS轻松扫描二维码
Posted aqi00
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android开发笔记(一百八十三)利用HMS轻松扫描二维码相关的知识,希望对你有一定的参考价值。
开源的android系统实际上只提供基本的系统服务,不提供常见的扩展服务诸如地图、邮箱、搜索、推送、机器学习、应用内支付等,这些扩展服务被谷歌公司打包成GMS套件(全称Google Mobile Service,中文名叫谷歌移动服务)。在海外市场,许多商用App都依赖于GMS提供的服务,手机缺少GMS会使得这些App没法使用,而手机厂商预装GMS套件需要获得谷歌公司授权。2019年华为公司遭到美国制裁,导致华为手机没能获得GMS授权,致使海外市场陷入寒冬。为此,华为公司推出了自主可控的HMS套件(全称Huawei Mobile Service,中文名叫华为移动服务),意图打破制裁。
HMS是华为公司提供的一套App扩展服务框架,它分为两部分,一部分是面向普通用户的预装App,包括花瓣地图、花瓣邮箱、花瓣搜索、花瓣支付等;另一部分是面向开发者的HMS Core,它给开发者提供API接口,用于在App开发时集成相关服务。HMS Core是华为移动服务提供的端、云开放能力的合集,包含华为账号、应用内支付、推送服务、游戏服务、定位服务、地图服务、广告服务和机器学习服务等,它的开源代码仓库地址为https://gitee.com/hms-core,开发者可在该仓库下载对应源码学习。
扫描二维码是HMS的一项基础服务,虽然谷歌公司也提供了zxing扫码框架,但是zxing框架的集成步骤不够简洁,而且它的识别速度偏慢,识别准确率也不高,远不如HMS的扫码服务来得好用。下面介绍如何在App工程中集成HMS的扫码服务。
首先,因为扫码属于第三方服务,所以要修改模块的build.gradle,往dependencies节点添加如下一行配置,表示导入指定版本的扫码库:
implementation 'com.huawei.hms:scanplus:1.3.1.300'
接着打开AndroidManifest.xml,补充以下的相机权限配置
<!-- 相机 -->
<uses-permission android:name="android.permission.CAMERA" />
然后在Java代码中增加用于扫码的远程视图,并指定扫码结果的回调事件,新增的代码片段如下所示:
private RemoteView remoteView; // 声明一个HMS的远程视图对象
private int SCAN_FRAME_SIZE = 240; // 扫码框的默认尺寸
// 添加扫码的远程视图
private void addRemoteView(Bundle savedInstanceState)
int screenWidth = Utils.getScreenWidth(this); // 获取屏幕宽度
int screenHeight = Utils.getScreenHeight(this); // 获取屏幕高度
int scanFrameSize = (int) (SCAN_FRAME_SIZE * Utils.getScreenDensity(this));
// 计算取景器的四周边缘。如果没有指定设置,它将位于布局的中间位置。
Rect rect = new Rect();
rect.left = screenWidth / 2 - scanFrameSize / 2;
rect.right = screenWidth / 2 + scanFrameSize / 2;
rect.top = screenHeight / 2 - scanFrameSize / 2;
rect.bottom = screenHeight / 2 + scanFrameSize / 2;
// 初始化远程视图实例
remoteView = new RemoteView.Builder().setContext(this)
.setBoundingBox(rect).setFormat(HmsScan.ALL_SCAN_TYPE).build();
// 当光线昏暗时,展示闪光灯开关按钮,以便用户决定是否开灯
remoteView.setOnLightVisibleCallback(visible ->
if (visible)
iv_flash.setVisibility(View.VISIBLE);
);
// 设置扫描结果的回调事件
remoteView.setOnResultCallback(result -> showResult(result));
// 将自定义视图加载到活动中.
remoteView.onCreate(savedInstanceState);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
rl_scan.addView(remoteView, params); // 往相对布局添加远程视图
// 显示扫码识别结果
private void showResult(HmsScan[] result)
if (result != null && result.length > 0 && result[0] != null &&
!TextUtils.isEmpty(result[0].getOriginalValue()))
Intent intent = new Intent(this, ScanResultActivity.class);
intent.putExtra(ScanUtil.RESULT, result[0]);
startActivity(intent); // 跳转到扫码结果页
在扫码结果页面,HMS不但支持获取结果文本,还支持获取条码的编码格式与结果类型,从而允许开发者更精准地辨别条码归属。下面是具体的扫码结果解析代码:
// 解析扫码结果
private void parserScanResult()
// 从意图中获取可折叠的扫码结果
HmsScan hmsScan = getIntent().getParcelableExtra(ScanUtil.RESULT);
try
String desc = String.format("扫码结果如下:\\n\\t\\t格式为%s\\n\\t\\t类型为%s\\n\\t\\t内容为%s",
getCodeFormat(hmsScan.getScanType()),
getResultType(hmsScan.getScanType(), hmsScan.getScanTypeForm()),
hmsScan.getOriginalValue());
tv_result.setText(desc);
catch (Exception e)
e.printStackTrace();
// 获取扫码格式
private String getCodeFormat(int scan_type)
String codeFormat = "未知(Unknown)";
if (scan_type == HmsScan.QRCODE_SCAN_TYPE)
codeFormat = "快速响应码(QR code)";
else if (scan_type == HmsScan.AZTEC_SCAN_TYPE)
codeFormat = "阿兹特克码(AZTEC code)";
else if (scan_type == HmsScan.DATAMATRIX_SCAN_TYPE)
codeFormat = "数据矩阵码(DATAMATRIX code)";
else if (scan_type == HmsScan.PDF417_SCAN_TYPE)
codeFormat = "便携数据文件码(PDF417 code)";
else if (scan_type == HmsScan.EAN13_SCAN_TYPE)
codeFormat = "欧洲商品编码-标准版(EAN13 code)";
else if (scan_type == HmsScan.EAN8_SCAN_TYPE)
codeFormat = "欧洲商品编码-缩短版(EAN8 code)";
else if (scan_type == HmsScan.ITF14_SCAN_TYPE)
codeFormat = "外箱条码(ITF14 code)";
else if (scan_type == HmsScan.UPCCODE_A_SCAN_TYPE)
codeFormat = "商品统一代码-通用(UPCCODE_A)";
else if (scan_type == HmsScan.UPCCODE_E_SCAN_TYPE)
codeFormat = "商品统一代码-短码(UPCCODE_E)";
else if (scan_type == HmsScan.CODABAR_SCAN_TYPE)
codeFormat = "库德巴码(CODABAR)";
return codeFormat;
// 获取结果类型
private String getResultType(int scan_type, int scanForm)
String resultType = "文本(Text)";
if (scan_type == HmsScan.QRCODE_SCAN_TYPE)
if (scanForm == HmsScan.PURE_TEXT_FORM)
resultType = "文本(Text)";
else if (scanForm == HmsScan.URL_FORM)
resultType = "网址(WebSite)";
// 此处省略若干格式判断
else if (scan_type == HmsScan.EAN13_SCAN_TYPE)
if (scanForm == HmsScan.ISBN_NUMBER_FORM)
resultType = "国际标准书号(ISBN)";
else if (scanForm == HmsScan.ARTICLE_NUMBER_FORM)
resultType = "产品(Product)";
else if (scan_type == HmsScan.EAN8_SCAN_TYPE
|| scan_type == HmsScan.UPCCODE_A_SCAN_TYPE
|| scan_type == HmsScan.UPCCODE_E_SCAN_TYPE)
if (scanForm == HmsScan.ARTICLE_NUMBER_FORM)
resultType = "产品(Product)";
return resultType;
接下来分别举个条形码例子与二维码例子,看看到底能扫出什么东西,条形码例子如下图所示,这是某个商品的条形码。
二维码例子如下图所示,这是清华大学的微信公众号二维码。
运行测试App,打开扫码界面如下图所示。
把扫码框对准条形码图片,App识别成功跳到结果页面如下图所示。
返回之后继续扫描二维码图片,App识别成功跳到结果页面如下图所示。
由此验证了HMS扫码服务的准确性和高效率。你还等什么呢?快来试试HMS的扫码服务吧,完整的范例源码见https://gitee.com/hms-core/hms-scan-demo。
以上是关于Android开发笔记(一百八十三)利用HMS轻松扫描二维码的主要内容,如果未能解决你的问题,请参考以下文章
Android开发笔记(一百八十九)利用LAME录制MP3音频