简介

华为统一扫码服务提供便捷的条形码和二维码扫描与解析能力,帮助您快速构建应用内的扫码功能。得益于华为在计算机视觉领域能力的积累,Scan Kit可以实现远距离二维码的检测与自动放大,从而解决远距离扫码场景中二维码难以识别的问题。同时,针对常见复杂扫码场景(如:强光照、污损、柱面等)做了针对性识别优化,提升扫码成功率与用户体验。

您将建立什么

在这个Codelab中,你将创建一个扫码APP。

您将会学到什么

硬件要求

  1. 安装了Android Studio的开发计算机。
  2. 华为手机一部,用于运行开发调试版本的扫码服务app。

软件要求

  1. Android Studio
  2. Java JDK 1.8及以上版本环境
  3. HMS Core为3.0.3.300及以上版本

若您需要正式发布集成Scan Kit的应用,请参考《HUAWEI HMS Core 集成准备》中详细说明来完成接入准备。
若您使用本Codelab Demo验证时,直接使用Sample Code中的设置,可以跳过此步骤。

Sample Code下载

针对AndroidStudio开发环境,华为提供了maven仓集成方式的HMS SDK包。在开始开发前,您需要将HMS SDK集成到您的AndroidStudio开发环境中。

1. 获取配置文件

a.登录 AppGallery Connect 网站,选择"我的应用"。在名称列表中找到应用所在的产品,点击对应手机设备的"Android应用"链接。

b.选择"开发 > 概览"。单击"应用"栏下的agconnect-services.json下载配置文件。

c.将agconnect-services.json文件拷贝到应用级根目录下。

2. 添加编译依赖

a.打开应用级build.gradle文件

b.在dependencies中添加如下编译依赖,{version} 需要替换为实际的SDK版本号,如:implementation 'com.huawei.hms:scan:1.1.1.301'

dependencies{ implementation 'com.huawei.hms:scan:{version}' }

c.同步工程。重新打开修改完的build.gradle文件,右上方出现Sync Now链接。点击Sync Now等待。如果出现错误,请检查网络连接是否正常,以及检查gradle文件是否正确。

在调用Scan Kit时,开发者需要先在Manifest中声明相应的权限。Android提供了两种扫码权限:CAMERA(相机权限)和READ_EXTERNAL_STORAGE(读文件权限)。

在AndroidManifest.xml文件中,增加:

<!--相机权限--> <uses-permission android:name="android.permission.CAMERA" /> <!--读文件权限--> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />

声明权限后,还需要在代码中动态申请一下权限。在MainActivity.java中,增加:

public void newViewBtnClick(View view) { //DEFINED_CODE为用户自定义用于接收权限校验结果 ActivityCompat.requestPermissions( this, new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE}, DEFINED_CODE); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (permissions == null || grantResults == null || grantResults.length < 2 || grantResults[0] != PackageManager.PERMISSION_GRANTED || grantResults[1] != PackageManager.PERMISSION_GRANTED) { return; } if (requestCode == DEFINED_CODE) { //跳转转扫码界面 this.startActivityForResult(new Intent(this, DefinedActivity.class), REQUEST_CODE_SCAN); } }

说明:已在示例sample demo code中权限申请,不需要重复申请。

Scan Kit提供4种不同的调用模式,具体的差别参见《开发指南》。本CodeLab选择了Customized View进行开发,实现扫码功能。

1. 自定义页面元素

开发者按需自定义页面元素,以下为一些常见的页面元素示例。属性未全部展示,详情请参考《开发指南》

1.自定义相机页面视图。在Sample Code app/src/main/res/layout/activity_defined.xml文件中,增加:

<FrameLayout android:id="@+id/rim" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#C0C0C0"> <SurfaceView android:id="@+id/surfaceView" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>

2.自定义返回键视图。在Sample Code app/src/main/res/layout/layout/activity_defined.xml文件中,增加:

<RelativeLayout android:layout_width="match_parent" android:layout_height="56dp" android:gravity="center_vertical"> <ImageView android:id="@+id/back_img" android:layout_width="48dp" android:layout_height="48dp" android:padding="12dp" android:layout_alignParentStart="true" android:layout_marginStart="12dp" android:layout_marginTop="4dp" android:gravity="center" android:src="@drawable/back" /> </RelativeLayout>

3.自定义扫码框。
在页面布局文件绘制扫码框,在Sample Code app/src/main/res/layout/layout/activity_defined.xml文件中,增加:

<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true" android:layout_centerHorizontal="true" android:background="#FF000000" android:alpha="0.1" /> <ImageView android:layout_width="300dp" android:layout_height="300dp" android:layout_centerInParent="true" android:layout_centerHorizontal="true" android:background="@drawable/scanningframe" /> </RelativeLayout>

Sample Code中创建app/src/main/res/layout/drawable/scanningframe.xml文件,并在其中设置扫码框样式

<?xml version="1.0" encoding="utf-8"?> <!-- 设置扫码框样式 --> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <!-- 设置边框的宽度和颜色 --> <stroke android:width="3dp" android:color="#e1ffff"/> <!-- 设置框内的填充色 --> <solid android:color="#1f00BCD4"/> <!-- 设置圆角 --> <corners android:radius="5dip"/> <!-- 设置内边距 --> <padding android:left="2dp" android:top="2dp" android:right="2dp" android:bottom="2dp" /> </shape>

2. 实现相机扫码操作

在自定义的Activity实现相机扫码操作,在Sample Code app/src/main/java/com/example/scankitdemo/DefinedActivity.java文件中,增加:

//请按AndroidStudio建议,导入所有依赖 private RemoteView remoteView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_defined); //设置扫码区域 Rect rect = new Rect(); rect.top = 100; rect.bottom = 2000; //初始化RemoteView并设置回调函数接收扫码结果 remoteView = new RemoteView.Builder().setContext(this).setBoundingBox(rect).setFormat(HmsScan.ALL_SCAN_TYPE).build(); remoteView.onCreate(savedInstanceState); remoteView.setOnResultCallback(new OnResultCallback() { @Override public void onResult(HmsScan[] result) { if (result != null && result.length > 0 && result[0] != null && !TextUtils.isEmpty(result[0].getOriginalValue())) { Intent intent = new Intent(); intent.putExtra(SCAN_RESULT, result[0]); setResult(RESULT_OK, intent); DefinedActivity.this.finish(); } } }); //将定义好的RemoteView添加到页面布局中 FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT); FrameLayout frameLayout = findViewById(R.id.rim); frameLayout.addView(remoteView, params); //设置返回键操作 ImageView backBtn = findViewById(R.id.back_img); backBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { DefinedActivity.this.finish(); } }); }

添加RemoteView的生命周期管理,在Sample Code app/src/main/java/com/example/scankitdemo/DefinedActivity.java文件中,增加如下代码:

@Override protected void onStart() { super.onStart(); remoteView.onStart(); } @Override protected void onResume() { super.onResume(); remoteView.onResume(); } @Override protected void onPause() { super.onPause(); remoteView.onPause(); } @Override protected void onDestroy() { super.onDestroy(); remoteView.onDestroy(); } @Override protected void onStop() { super.onStop(); remoteView.onStop(); }

3. 处理扫码结果

在MainActivity中处理扫码结果,在Sample Code app/src/main/java/com/example/scankitdemo/MainActivity.java文件中,增加:

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { //Receive result super.onActivityResult(requestCode, resultCode, data); if (resultCode != RESULT_OK || data == null) { return; } if (requestCode == REQUEST_CODE_SCAN) { HmsScan hmsScan = data.getParcelableExtra(DefinedActivity.SCAN_RESULT); if (hmsScan != null && !TextUtils.isEmpty(hmsScan.getOriginalValue())) { Toast.makeText(MainActivity.this, hmsScan.getOriginalValue(), Toast.LENGTH_SHORT).show(); } } }

完成开发后,点击开发界面上的图标,运行Android Studio工程打包生成APK,并安装在测试手机上。运行界面如下图所示:

干得好,你已经成功完成了Codelab并学到了:

  1. 如何集成华为Scan Kit。
  2. 如何调用华为Scan Kit的能力进行扫码。

如需了解更多与华为Scan Kit相关的信息,请关注我们的官方网站。开发过程中如果遇见问题,请参考我们的常见问题解答。

您可以阅读下面链接,了解更多相关的信息。

本CodeLab中的demo源码下载地址如下:

完整源码下载

已复制代码