Android扫描二维码(基于华为HMS Core)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android扫描二维码(基于华为HMS Core)相关的知识,希望对你有一定的参考价值。

一、背景

之前一直用开源的Zxing来扫描二维码,但是随着使用场景的复杂,Zxing的识别就捉襟见肘了。很多场景下Zxing都很难识别,比如:绿底白纹的二维码;光线较暗的场景;二维码比较小的场景……

用户在识别的时候,会去与微信支付宝的二维码识别做比较,如果微信支付宝能识别,而我们自己的APP无法识别,用户评价就会极其糟糕。

我们这里就找到了更好的二维码识别方案,就是基于华为的HMS Core的二维码识别功能。

二、开发准备

​HMS Core官网​

1、首先登录​AppGallery Connect​网站,添加项目,项目中再添加应用。

2、在“项目设置 > 常规”页面的“应用”区域,点击“agconnect-services.json”下载配置文件。

Android扫描二维码(基于华为HMS

3、将“agconnect-services.json”文件拷贝到应用级根目录下。

Android扫描二维码(基于华为HMS

4、配置项目级的build.gradle

buildscript 
repositories
google()
jcenter()
// 配置HMS Core SDK的Maven仓地址。
maven url https://developer.huawei.com/repo/

dependencies
...
// 增加AGC插件配置,请您参见AGC插件依赖关系选择合适的AGC插件版本。
classpath com.huawei.agconnect:agcp:1.6.0.300



allprojects
repositories
google()
jcenter()
// 配置HMS Core SDK的Maven仓地址。
maven url https://developer.huawei.com/repo/

5、在app级的build.gradle中引用依赖

dependencies 
...
implementation com.huawei.hms:scan:2.6.0.300

在文件头部声明

apply plugin: com.huawei.agconnect

三、构建代码

1、调用默认界面
HmsScanAnalyzerOptions options = new HmsScanAnalyzerOptions.Creator()
.setHmsScanTypes(HmsScan.QRCODE_SCAN_TYPE, HmsScan.DATAMATRIX_SCAN_TYPE)//此处配置识别二维码格式
.create();
ScanUtil.startScan(this, REQUEST_CODE_SCAN_ONE, options);

使用onActivityResult接收扫码结果

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK || data == null)
return;

if (requestCode == REQUEST_CODE_SCAN_ONE)
// 导入图片扫描返回结果
HmsScan obj = data.getParcelableExtra(ScanUtil.RESULT);
if (obj != null)
// 展示解码结果
showResult(obj);


2、自定义扫码界面

自定义Activity:DefinedActivity

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.huawei.hms.hmsscankit.OnLightVisibleCallBack;
import com.huawei.hms.hmsscankit.OnResultCallback;
import com.huawei.hms.hmsscankit.RemoteView;
import com.huawei.hms.hmsscankit.ScanUtil;
import com.huawei.hms.ml.scan.HmsScan;
import com.huawei.hms.ml.scan.HmsScanAnalyzerOptions;

import java.io.IOException;

public class DefinedActivity extends Activity
private FrameLayout frameLayout;
private RemoteView remoteView;
private ImageView backBtn;
private ImageView imgBtn;
private ImageView flushBtn;
int mScreenWidth;
int mScreenHeight;
//The width and height of scan_view_finder is both 240 dp.
final int SCAN_FRAME_SIZE = 240;

private int[] img = R.drawable.flashlight_on, R.drawable.flashlight_off;
private static final String TAG = "DefinedActivity";

//Declare the key. It is used to obtain the value returned from Scan Kit.
public static final String SCAN_RESULT = "scanResult";
public static final int REQUEST_CODE_PHOTO = 0X1113;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_defined);
// Bind the camera preview screen.
frameLayout = findViewById(R.id.rim);

//1. Obtain the screen density to calculate the viewfinders rectangle.
DisplayMetrics dm = getResources().getDisplayMetrics();
float density = dm.density;
//2. Obtain the screen size.
mScreenWidth = getResources().getDisplayMetrics().widthPixels;
mScreenHeight = getResources().getDisplayMetrics().heightPixels;

int scanFrameSize = (int) (SCAN_FRAME_SIZE * density);

//3. Calculate the viewfinders rectangle, which in the middle of the layout.
//Set the scanning area. (Optional. Rect can be null. If no settings are specified, it will be located in the middle of the layout.)
Rect rect = new Rect();
rect.left = mScreenWidth / 2 - scanFrameSize / 2;
rect.right = mScreenWidth / 2 + scanFrameSize / 2;
rect.top = mScreenHeight / 2 - scanFrameSize / 2;
rect.bottom = mScreenHeight / 2 + scanFrameSize / 2;


//Initialize the RemoteView instance, and set callback for the scanning result.
remoteView = new RemoteView.Builder().setContext(this).setBoundingBox(rect).
// setFormat(HmsScan.ALL_SCAN_TYPE). //此处设置二维码格式
build();
// When the light is dim, this API is called back to display the flashlight switch.
flushBtn = findViewById(R.id.flush_btn);
remoteView.setOnLightVisibleCallback(new OnLightVisibleCallBack()
@Override
public void onVisibleChanged(boolean visible)
if(visible)
flushBtn.setVisibility(View.VISIBLE);


);
// Subscribe to the scanning result callback event.
remoteView.setOnResultCallback(new OnResultCallback()
@Override
public void onResult(HmsScan[] result)
//Check the 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();


);
// Load the customized view to the activity.
remoteView.onCreate(savedInstanceState);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
frameLayout.addView(remoteView, params);
// Set the back, photo scanning, and flashlight operations.
setBackOperation();
setPictureScanOperation();
setFlashOperation();


/**
* Call the lifecycle management method of the remoteView activity.
*/
private void setPictureScanOperation()
imgBtn = findViewById(R.id.img_btn);
imgBtn.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Intent pickIntent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
DefinedActivity.this.startActivityForResult(pickIntent, REQUEST_CODE_PHOTO);


);


private void setFlashOperation()
flushBtn.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
if (remoteView.getLightStatus())
remoteView.switchLight();
flushBtn.setImageResource(img[1]);
else
remoteView.switchLight();
flushBtn.setImageResource(img[0]);


);


private void setBackOperation()
backBtn = findViewById(R.id.back_img);
backBtn.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
DefinedActivity.this.finish();

);


/**
* Call the lifecycle management method of the remoteView activity.
*/
@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();


/**
* Handle the return results from the album.
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE_PHOTO)
try
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), data.getData());
HmsScan[] hmsScans = ScanUtil.decodeWithBitmap(DefinedActivity.this, bitmap, new HmsScanAnalyzerOptions.Creator().setPhotoMode(true).create());
if (hmsScans != null && hmsScans.length > 0 && hmsScans[0] != null && !TextUtils.isEmpty(hmsScans[0].getOriginalValue()))
Intent intent = new Intent();
intent.putExtra(SCAN_RESULT, hmsScans[0]);
setResult(RESULT_OK, intent);
DefinedActivity.this.finish();

catch (IOException e)
e.printStackTrace();



调用DefinedActivity

Intent intent = new Intent(mUniSDKInstance.getContext(), DefinedActivity.class);
((Activity)mUniSDKInstance.getContext()).startActivityForResult(intent, REQUEST_CODE);

接收结果

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
if(requestCode == REQUEST_CODE && data.hasExtra("respond"))
Log.e("Test", "原生页面返回----"+data.getStringExtra("respond"));

else
super.onActivityResult(requestCode, resultCode, data);

3、图片解析模式

还有种解析图片的模式,这里就不做介绍了,自行查找​​官网​​中的说明。




以上是关于Android扫描二维码(基于华为HMS Core)的主要内容,如果未能解决你的问题,请参考以下文章

分享一下华为的二维码条形码识别(Android)

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

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

想问华为hms,core啥意思

华为HMS Core携手超图为三维GIS注入新动能

华为在HDC2021发布全新HMS Core 6 宣布跨OS能力开放