前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android开发笔记(一百八十三)利用HMS轻松扫描二维码

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

作者头像
aqi00
发布2022-05-11 09:53:03
1.2K0
发布2022-05-11 09:53:03
举报
文章被收录于专栏:老欧说安卓

开源的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节点添加如下一行配置,表示导入指定版本的扫码库:

代码语言:javascript
复制
implementation 'com.huawei.hms:scanplus:1.3.1.300'

接着打开AndroidManifest.xml,补充以下的相机权限配置

代码语言:javascript
复制
<!-- 相机 -->
<uses-permission android:name="android.permission.CAMERA" />

然后在Java代码中增加用于扫码的远程视图,并指定扫码结果的回调事件,新增的代码片段如下所示:

代码语言:javascript
复制
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不但支持获取结果文本,还支持获取条码的编码格式与结果类型,从而允许开发者更精准地辨别条码归属。下面是具体的扫码结果解析代码:

代码语言:javascript
复制
// 解析扫码结果
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。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-03-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档