开源的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开发笔记的完整目录

Android开发笔记(一百八十三)利用HMS轻松扫描二维码相关推荐

  1. Android开发笔记(八十三)多语言支持

    汉字转拼音 app中有许多场景要对汉字排序,例如通讯录姓名.商品名称.城市名称等等,这些汉字词汇通常是按照拼音排序,所以产生了把汉字转换为拼音的需求. Android自带库 Android自带的联系人 ...

  2. Android开发丶openinstall的集成和使用(推广二维码)

    在项目开发过程中,负责的推广二维码模块需要加入openinstall三方框架,该框架可以在推广二维码中搭建一层上下级关系,加上一定的积分奖励,极大地提高了用户的推广热情,并且不同于以往常规的手动填写邀 ...

  3. Android开发笔记(八十)运行状态检查

    大家都知道刻舟求剑的寓言故事,说的是事物是发展变化着的,如果拘泥于原来的情况,那随着情况的改变,就不会得到预期的结果.同样,影响app运行的因素,并不只是外部环境(如硬件.系统.权限等等),还包括ap ...

  4. Android开发笔记(八十九)单例模式

    基本概念 单例模式是一种常用的软件设计模式,它确保一个类只有一个实例,从而方便对实例个数的控制并节约系统资源. 单例模式有三个特点: 1.某个类只能有一个实例: 2.它要自行创建这个实例: 3.它只有 ...

  5. Android开发笔记(八十六)几个特殊的类

    接口interface interface是一些功能的集合,但它只定义了对象必须实现的成员,而不包含成员的实现代码,成员的具体代码由实现接口的类提供.Android对接口的使用场景主要有三类:事件监听 ...

  6. Android开发笔记(八十八)同步与加锁

    同步synchronized 同步方法 synchronized可用来给方法或者代码块加锁,当它修饰一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码.这就意味着,当两个并发线程同时访 ...

  7. Android开发笔记(八十七)几个修饰关键字

    原生native native是方法修饰符,表示该方法是由其他一种语言(如C/C++)实现的原生方法.其实native只在JNI接口中使用,java代码中只有原生方法的定义,具体的实现代码在其他语言( ...

  8. Android开发笔记(六十三)HTTP访问的通信方式

    InputStream和OutputStream 输入输出流在java中很常用,从文件读写到内存读写到网络通信都会用到.在之前的< Android开发笔记(三十三)文本文件和图片文件的读写> ...

  9. (转载)Android项目实战(二十八):使用Zxing实现二维码及优化实例

    Android项目实战(二十八):使用Zxing实现二维码及优化实例 作者:听着music睡 字体:[增加 减小] 类型:转载 时间:2016-11-21 我要评论 这篇文章主要介绍了Android项 ...

  10. Android安卓开发集成微信第三方扫描二维码登录-超级无敌具详细

    Android安卓开发中集成微信二维码登录的步骤: 写在前面的: 该教程使用AS作为演示,使用ecplise请参照微信官方文档下载相应jar等所需参考文档和资源.在最后,我会附上这个Activity的 ...

最新文章

  1. adc采样时间_ADC采样原理
  2. 寻找两个正序数组的中位数Python解法
  3. git提交代码到自己的分支,并合并到主分支的完整流程。
  4. java mail 已发送_JavaMail获取已发送邮件
  5. 微信帐号被封零钱怎么办?微信针对封停帐号的零钱提取出了一个流程
  6. [书目20161206]小狗钱钱的人生整理术
  7. python+selenium+appium遇到的环境问题(已解决)
  8. 在线图像识别相似图片_宋源:图像识别传感器在制桶设备上的应用(附视频)...
  9. 计算机应用基本技能题库,计算机应用基本技能技能考试题库.pdf
  10. 零基础入门语义分割-Task6 分割模型模型集成
  11. java窗口淡出_java淡入淡出式显示gui
  12. To prevent a memory leak the JDBC Driver has been forcibly
  13. mybatis当传入数据类型为Int时并且值为0时,会判断为空字符串
  14. OPENWRT-LUCI开发总结-LUCI开发过程中的小技巧
  15. 2020阿里招聘岗位要求
  16. 微信小程录制视频上传服务器,微信小程序-从相册获取图片,视频使用相机拍照,录像上传+服务器nodejs版接收-微信小程序视频上传功能-微信小程序视频上传...
  17. Java对象转xml
  18. mysql slave running_MySQL主从复制出现Slave_IO_Running,Slave_SQL_Running解决方法
  19. kubernetes上部署rook-ceph存储系统
  20. 林书豪028-三人的回应

热门文章

  1. 人工智能中的图像识别技术
  2. 3D游戏角色模型设计都要学习什么?
  3. ap启动失败 ensp_eNSP模拟WLAN——上线华为真实AP的方法及配置
  4. java jbutton 大小_Java swing JButton的顺序和大小
  5. bandicam去水印
  6. 数据仓库模型设计与工具
  7. 网上邻居找不到服务器怎么办,Win7网上邻居消失了怎么办?Win7网上邻居不能使用的原因及解决方法...
  8. 02:Glove论文学习
  9. 佳能mf4400打印机无线服务器,佳能Canon imageCLASS MF4400 驱动
  10. Android:ViewPage使用教程