【Android App】人脸识别中扫描识别二维码实战解析(附源码和演示 超详细)

news/2025/2/11 21:26:23/

需要源码请点赞关注收藏后评论区留言私信~~~

一、扫描识别二维码

不仅可以利用zxing库生成二维码,同样利用zxing库可以扫描二维码并解析得到原始文本,此时除了给build.gradle添加如下一行依赖配置

implementation 'com.google.zxing:core:3.4.1'

还需要给App工程引入代码包com.app.zxing 可以私信博主要

同时扫描会用到手机摄像头,因此要给App添加相机权限,如果识别出二维码之时需要震动手机提醒用户,还得申请震动权限

使用Zxing库在代码中增加扫码的支撑操作,主要实现三个功能点:

(1)初始化相机并开始扫码

因为com.app.zxing包重新封装系统的相机工具,并提供了扫码专用的相机管理器CameraManager,所以若要打开相机只需调用CameraManager的openDriver方法,关闭相机则需要调用closeDriver方法

(2)处理扫码结束后的提示音响

通常扫码结束会发出滴的声音,提示用户已经识别出二维码内容,请及时关注App后续处理,这个提示音可采用媒体播放器MediaPlayer播放,在扫码前初始化播放器对象,待扫码完成再调用播放器的start方法,除了滴的提示音,震动提示也很常见

(3)处理扫码识别到的文本信息

扫码识别的二维码内容其实是一个字符串,有时为HTTP链接,有时为其他协议的地址,总之拿到结果字符串后,App还得根据链接地址区分处理,要么打开新链接页面,要么完成支付操作,要么启动某个App

扫码后识别字符串文本效果如下 字符串可以自己手动输入

读者可以自行扫描下方二维码体验效果 

 

 

 代码如下

package com.example.face;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Vibrator;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;import com.app.zxing.camera.CameraManager;
import com.app.zxing.decoding.CaptureActivityHandler;
import com.app.zxing.decoding.InactivityTimer;
import com.app.zxing.view.ViewfinderView;
import com.example.face.util.QrcodeUtil;
import com.google.zxing.Result;public class ScanQrcodeActivity extends AppCompatActivity implements SurfaceHolder.Callback {private final static String TAG = "ScanQrcodeActivity";private int CHOOSE_CODE = 3; // 只在相册挑选图片的请求码private ViewfinderView vv_finder; // 定义一个扫码视图对象private boolean hasSurface = false; // 是否创建了渲染表面private CaptureActivityHandler mHandler; // 捕捉图像的处理器private InactivityTimer mTimer; // 结束活动的计时器private MediaPlayer mPlayer; // 声明一个媒体播放器对象@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_scan_qrcode);findViewById(R.id.iv_back).setOnClickListener(v -> finish());TextView tv_title = findViewById(R.id.tv_title);tv_title.setText("二维码扫描/条形码扫描");TextView tv_option = findViewById(R.id.tv_option);tv_option.setVisibility(View.VISIBLE);tv_option.setText("相册");tv_option.setOnClickListener(v -> {// 创建一个内容获取动作的意图(准备跳到系统相册)Intent albumIntent = new Intent(Intent.ACTION_GET_CONTENT);albumIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false); // 是否允许多选albumIntent.setType("image/*"); // 类型为图像startActivityForResult(albumIntent, CHOOSE_CODE); // 打开系统相册});CameraManager.init(getApplication(), CameraManager.QR_CODE);vv_finder = findViewById(R.id.vv_finder);}@Overrideprotected void onResume() {super.onResume();mTimer = new InactivityTimer(this);SurfaceView sv_scan = findViewById(R.id.sv_scan);// 从表面视图获取表面持有者SurfaceHolder surfaceHolder = sv_scan.getHolder();if (hasSurface) { // 已创建渲染表面initCamera(surfaceHolder); // 初始化相机} else { // 未创建渲染表面surfaceHolder.addCallback(this);}initBeepSound(); // 初始化哔哔音效}@Overrideprotected void onPause() {super.onPause();if (mHandler != null) {mHandler.quitSynchronously();mHandler = null;}CameraManager.get().closeDriver();}@Overrideprotected void onDestroy() {super.onDestroy();mTimer.shutdown();}// 处理实时扫描获得的二维码信息public void handleDecode(Result result, Bitmap barcode) {mTimer.onActivity();beepAndVibrate(); // 震动手机并发出哔的一声// 读取二维码分析后的结果字符串String resultStr = result.getText();if (TextUtils.isEmpty(resultStr)) {Toast.makeText(this, "扫码失败或者结果为空", Toast.LENGTH_SHORT).show();} else {//Toast.makeText(this, "扫码结果为"+resultStr, Toast.LENGTH_SHORT).show();gotoResultPage(resultStr); // 跳到扫描结果页面}}// 跳到扫描结果页面private void gotoResultPage(String resultStr) {Intent intent = new Intent(this, ScanResultActivity.class);intent.putExtra("result", resultStr);startActivity(intent);}// 初始化相机private void initCamera(SurfaceHolder surfaceHolder) {try {CameraManager.get().openDriver(surfaceHolder);if (mHandler == null) {mHandler = new CaptureActivityHandler(this, null, null);}} catch (Exception e) {e.printStackTrace();}}// 在渲染表面变更时触发@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}// 在渲染表面创建时触发@Overridepublic void surfaceCreated(SurfaceHolder holder) {if (!hasSurface) {hasSurface = true;initCamera(holder);}}// 在渲染表面销毁时触发@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {hasSurface = false;}public ViewfinderView getViewfinderView() {return vv_finder;}public Handler getHandler() {return mHandler;}// 描绘扫码时的动态横杠public void drawViewfinder() {vv_finder.drawViewfinder();}// 初始化哔哔音效private void initBeepSound() {if (mPlayer == null) {// 设置当前页面的音频流类型setVolumeControlStream(AudioManager.STREAM_MUSIC);mPlayer = new MediaPlayer(); // 创建一个媒体播放器// 设置媒体播放器的音频流类型mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);// 设置媒体播放器的播放结束监听器mPlayer.setOnCompletionListener(player -> player.seekTo(0));try (AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.beep)) {// 设置媒体播放器的媒体数据来源mPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());mPlayer.setVolume(0.1f, 0.1f); // 设置媒体播放器的左右声道音量mPlayer.prepare(); // 媒体播放器准备就绪} catch (Exception e) {e.printStackTrace();mPlayer = null;}}}// 震动手机并发出哔的一声private void beepAndVibrate() {if (mPlayer != null) {mPlayer.start(); // 媒体播放器开始播放}// 从系统服务中获取震动器Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);vibrator.vibrate(200); // 命令震动器震动若干秒}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent intent) {super.onActivityResult(requestCode, resultCode, intent);if (resultCode == RESULT_OK && requestCode == CHOOSE_CODE) { // 从相册返回if (intent.getData() != null) { // 从相册选择一张照片// 开启分线程从相册的图片Uri中解析二维码new Thread(() -> parserImage(intent.getData())).start();}}}// 从相册的图片Uri中解析二维码private void parserImage(Uri uri) {try {Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);Result result = QrcodeUtil.parserQrcode(bitmap); // 从位图中解析二维码if (result == null) {Looper.prepare();Toast.makeText(this, "无法解析图片中的二维码", Toast.LENGTH_SHORT).show();Looper.loop();} else {String resultStr = QrcodeUtil.reEncode(result.toString());Log.d(TAG, "resultStr="+resultStr);gotoResultPage(resultStr); // 跳到扫描结果页面}} catch (Exception e) {e.printStackTrace();}}}

创作不易 觉得有帮助请点赞关注收藏~~~


http://www.ppmy.cn/news/1067.html

相关文章

编程语言介绍

第一节 什么是编程语言 1.1 定义 ------------------------------------------------------------------------------------------------------------------------------- 编程语言(programming language),是用来定义计算机程序的形…

Yolo算法检测之NMS(非极大值抑制)原理详解

刚开始学习算法的时候,nms非极大值一直学不明白,今天终于搞明白了,大致总结一下。 首先我们简单看一下NMS使用的这个背景 按照yolo目标检测算法的初步思想来说,把图片分成19*19网格之后,理论上这个19*19个网格里面包含…

基于PHP+MySQL月子中心管理系统的设计与实现

月子中心管理系统是信息时代的产物,月子基本是每个适龄女子都会经历的一个特殊时期,尤其是在中国对月子的重视程度尤其的重要,只有让产妇和婴儿受到精心的照顾才能够让产妇更好的康复,才能够让婴儿更好的成长,所以越来越多的人关注到了月子期间的养护问题,为了能够让更多的月子…

关于K8s中资源服务质量管理Resource Qos的一些笔记整理

写在前面 分享一些 K8s中资源服务质量管理Resource Qos 的笔记博文内容涉及: K8s Qos 简单介绍资源配置的特点: 节点的超用,可压缩/不可压缩,完全可靠性等介绍QoS Classes 介绍三种 Qos 服务质量等级定义的 Demo 理解不足小伙伴帮忙指正 精神的寓所是我们…

ABC 分析法(帕累托分析法、2/8分析法)

在任何特定群体中,重要的因子通常只占少数,而不重要的因子则占多数,因此只要能控制具有重要性的少数因子即能控制全局。例如,在企业中,通常认为它80%的利润来自于20%的项目或重要客户;全球最富有的 20% 人口…

业务流程管理的未来趋势:个性化定制

自进入互联网时代以来、甚至更早,无论是从物质还是精神层面,“个性化”已经成为大众所普遍追求的东西。个性化定制允许买家按照自身偏好对产品进行二次改造,例如许多汽车品牌,就可以根据车主的想法来实现定制。 其实,…

正式练习的第一个Python功能:加法计算

我本身有着C/C的功底,最近开始自学python,包括网上找教程,买书看。不确定我这种有其他编程语言经验的再学新的语言算不算零基础,总之书就买的《零基础学Python程序设计》。鉴于自己之前已经看过一段时间,这个程序也就不…

java中的静态代理、jdk动态代理以及CGLIB 动态代理

代理模式是一种比较好理解的设计模式。简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能 那以下文章主要谈三种代理模式,分别是静…