Android我的二维码扫描功能发展史(完整)

2024-06-24 13:18

本文主要是介绍Android我的二维码扫描功能发展史(完整),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近在研究下二维码扫描功能,跟据从网上查阅的资料到自己勉强已实现扫描功能来一一介绍我的二维码扫描功能实现的发展历程:
首页通过网络搜索发现做android二维码扫描功能看去都是基于google的ZXing项目开发。
2、搜索怎么使用ZXing实现自己的二维码扫描:从网上下载ZXing-2.2.zip以及core-2.2-source.jar文件,分别解压两个文件。然后把.jar解压出来的整个com文件夹copy到ZXing文件夹内andorid目录中src下(里面也有个com文件夹)选择覆盖。然后就会发现里面的client文件夹内有多个result文件夹。
下面全都是以在2.2版本为例
3、把ZXing内的android/src/com文件夹copy到你自己项目src下。然后又把res那些资源文件也copy到自己项目中对应的目录下。有报错则按提示改,一般是报R文件的引用问题,当然还有一小部分是文件类引用问题,进入报错类的源码看下引用类的方法已改成什么,按照说明改下(清单文件中的启动类要改成自己的,ZXing中启动的是CaptureActivity)。
4、修改CaptureActivity类中handleDecode方法,这个方法的作用是解码已扫到的内容。我是参照网上的写法自己再稍加修改下。

public void handleDecode(Result rawResult, Bitmap barcode, float scaleFactor) {final String result = rawResult.getText().toString();if (!TextUtils.isEmpty(result)) {Intent intent = new Intent();Bundle bundle = new Bundle();bundle.putString("scan_result", rawResult.getText());bundle.putParcelable("bitmap",barcode);intent.putExtras(bundle);setResult(RESULT_OK, intent);} else {setResult(RESULT_CANCELED);}finish();}

5、在main.xml文件中创建button跟TextView以及ImageView控件,然后在MainActivity中通过按钮监听事件中启动相机也就是扫描功能并返回结果,SCAN_CODE是常量自己定义。

 Button button = (Button) findViewById(R.id.scan_button);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, CaptureActivity.class);startActivityForResult(intent, SCAN_CODE);}});

6、通过onActivityResult方法把值获取出来并显示在控件上

 @Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {switch (requestCode) {case SCAN_CODE:TextView scanResult = (TextView) findViewById(R.id.scan_result);if (resultCode == RESULT_OK) {final String result = data.getStringExtra("scan_result");iv.setImageBitmap((Bitmap) data.getParcelableExtra("bitmap"));scanResult.setText(result);if(isValideUrl(result)){new AlertDialog.Builder(this).setTitle("扫描结果").setMessage(result).setPositiveButton("打开", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {Intent intent = new Intent();intent.setClass(MainActivity.this,WebViewAct.class);intent.putExtra("url",result);startActivity(intent);MainActivity.this.finish();}}).setNegativeButton("取消", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();}}).show();}} else if (resultCode == RESULT_CANCELED) {scanResult.setText("没有扫描出结果");}break;}}

到这里就已经能实现扫描功能了,而我还在这方法里面加个判断获取到的内容值是否为有效的网址,如果是的话则弹出提示是否打开。我这里先给出判断方法

 /*** 判断是否是网址*/public boolean isValideUrl(String text){Pattern p = Pattern.compile("((http|ftp|https)://)(([a-zA-Z0-9\\._-]+\\.[a-zA-Z]{2,6})|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(:[0-9]{1,4})*(/[a-zA-Z0-9\\&%_\\./-~-]*)?", Pattern.CASE_INSENSITIVE);if(p.matcher(text).matches()){return true;}return false;}

而跳转的WebViewAct.class是自己写的:

package com.google.zxing.client.android;import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.webkit.WebView;import com.example.qrcodetest.R;/*** Created by xiaoli.yang on 2016/7/27.*/
public class WebViewAct extends Activity {private WebView mWebView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.webview);Bundle extras =this.getIntent().getExtras();String  url= extras.getString("url");Log.i("**获取到的url值为******",url);mWebView = (WebView) findViewById(R.id.web_view);mWebView.loadUrl(url);}

从代码中可以看到,我把这个类也写到com.google.zxing.client.android这个包下,方便统一更改。
《—————————————–分割线——————————————-》
上面已实现扫描功能,但扫描界面是横向的,我们一般都是竖直方向用的,so改方向。
0、按照网上各大神教的,我这算是整合吧,因为我是用红米测的所以可能是手机原因还要继续改些其他的代码。
1、我这里先贴出网上改的,就不用再找了,然后我再说我自己又改了哪些。
1) 在AndroidManifest.xml中把 标签 CaptureActivity 的screenOrientation修改为

android:screenOrientation="portrait"

2) 在CameraManager.java类中的getFramingRectInPreview()替换掉原先的 left right top bottom

//竖屏  
rect.left = rect.left * cameraResolution.y / screenResolution.x;   
rect.right = rect.right * cameraResolution.y / screenResolution.x;   
rect.top = rect.top * cameraResolution.x / screenResolution.y;   
rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;

3) 在CameraConfigurationManager.java中void setDesiredCameraParameters(Camera camera)方法在setParameters之前增加

camera.setDisplayOrientation(90);

4) 在DecodeHandler.java中的 decode(byte[] data, int width, int height)方法在

PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(data, width, height);之前添加:

byte[] rotatedData = new byte[data.length];   for (int y = 0; y < height; y++) {   for (int x = 0; x < width; x++)   rotatedData[x * height + height - y - 1] = data[x + y * width];   }   int tmp = width; // Here we are swapping, that's the difference to #11   width = height;   height = tmp;   data = rotatedData; 

我这是2.2的里面代码是 PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height); 以免有的人找不到。

5)进入com.google.zxing.client.android.camera包下的CameraConfigurationManager类:在Log.i(TAG, “Screen resolution: ” + screenResolution)的下面添加:

  Point screenResolutionForCamera = new Point();  screenResolutionForCamera.x = screenResolution.x;  screenResolutionForCamera.y = screenResolution.y;  if (screenResolution.x < screenResolution.y) {  screenResolutionForCamera.x = screenResolution.y;  screenResolutionForCamera.y = screenResolution.x;  }  cameraResolution = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolutionForCamera);  

加上最后一句发现有报错,我自己是直接把最后一句注释掉。

6)进入com.google.zxing.client.android包下的CaptureActivity类:注释以下代码:

   if (prefs.getBoolean(PreferencesActivity.KEY_DISABLE_AUTO_ORIENTATION, true)) {  setRequestedOrientation(getCurrentOrientation());  } else {  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);  }  

但我在这个类中并没有找到这些内容,只注释掉

copyToClipboard = prefs.getBoolean(PreferencesActivity.KEY_COPY_TO_CLIPBOARD, true)&& (intent == null || intent.getBooleanExtra(Intents.Scan.SAVE_HISTORY, true));

这个,功能是一样的。
并且另外在这个类的onCreate方法最后加上

if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);} else {setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);}

然后运行。。。。。。

发现横竖屏是切换了,但是取景框的位置却没在中间,另外取景框感觉太小了。而且扫描二维码却扫不出来,把屏幕再倒回横屏却意外发现可以扫描。解决这些问题方法如下:
在CameraConfigurationManager类中的initFromCameraParameters方法内注释掉这段代码:

 //横竖屏切换后取不到值,注释掉测试
//    if (width >height) {
//      Log.i(TAG, "Display reports portrait orientation; assuming this is incorrect");
//      int temp = width;
//      width = height;
//      height = temp;
//    }

调整取景框大小以及位置:
在CameraManager类中把框高都设置成540

private static final int MIN_FRAME_WIDTH = 540;//original 240private static final int MIN_FRAME_HEIGHT = 540; //original 240private static final int MAX_FRAME_WIDTH = 540; // = 1920/2 original 960private static final int MAX_FRAME_HEIGHT = 540; // = 1080/2 original 540

original后面的值是原本的内容。在getFramingRect方法中通过改变

int leftOffset = (screenResolution.x - width)/2;int topOffset = (screenResolution.y - height)/2;

这个两个2个值就能改变取景框的位置了。

以上就是我实现扫描功能的发展史,取景界面仿微信那些还不会。。。正在研究中。
下载资源地址:http://download.csdn.net/detail/u012138137/9589939 要1积分,嘿嘿。。。

在com.google.zxing.client.android包下的WebViewAct类中的onCreate方法最下面加上finish();不然跳转到webkit后返回会先有空白页,再按返回才行。

这篇关于Android我的二维码扫描功能发展史(完整)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1090256

相关文章

Eclipse+ADT与Android Studio开发的区别

下文的EA指Eclipse+ADT,AS就是指Android Studio。 就编写界面布局来说AS可以边开发边预览(所见即所得,以及多个屏幕预览),这个优势比较大。AS运行时占的内存比EA的要小。AS创建项目时要创建gradle项目框架,so,创建项目时AS比较慢。android studio基于gradle构建项目,你无法同时集中管理和维护多个项目的源码,而eclipse ADT可以同时打开

android 免费短信验证功能

没有太复杂的使用的话,功能实现比较简单粗暴。 在www.mob.com网站中可以申请使用免费短信验证功能。 步骤: 1.注册登录。 2.选择“短信验证码SDK” 3.下载对应的sdk包,我这是选studio的。 4.从头像那进入后台并创建短信验证应用,获取到key跟secret 5.根据技术文档操作(initSDK方法写在setContentView上面) 6.关键:在有用到的Mo

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

android 带与不带logo的二维码生成

该代码基于ZXing项目,这个网上能下载得到。 定义的控件以及属性: public static final int SCAN_CODE = 1;private ImageView iv;private EditText et;private Button qr_btn,add_logo;private Bitmap logo,bitmap,bmp; //logo图标private st

Android多线程下载见解

通过for循环开启N个线程,这是多线程,但每次循环都new一个线程肯定很耗内存的。那可以改用线程池来。 就以我个人对多线程下载的理解是开启一个线程后: 1.通过HttpUrlConnection对象获取要下载文件的总长度 2.通过RandomAccessFile流对象在本地创建一个跟远程文件长度一样大小的空文件。 3.通过文件总长度/线程个数=得到每个线程大概要下载的量(线程块大小)。

时间服务器中,适用于国内的 NTP 服务器地址,可用于时间同步或 Android 加速 GPS 定位

NTP 是什么?   NTP 是网络时间协议(Network Time Protocol),它用来同步网络设备【如计算机、手机】的时间的协议。 NTP 实现什么目的?   目的很简单,就是为了提供准确时间。因为我们的手表、设备等,经常会时间跑着跑着就有误差,或快或慢的少几秒,时间长了甚至误差过分钟。 NTP 服务器列表 最常见、熟知的就是 www.pool.ntp.org/zo

高仿精仿愤怒的小鸟android版游戏源码

这是一款很完美的高仿精仿愤怒的小鸟android版游戏源码,大家可以研究一下吧、 为了报复偷走鸟蛋的肥猪们,鸟儿以自己的身体为武器,仿佛炮弹一样去攻击肥猪们的堡垒。游戏是十分卡通的2D画面,看着愤怒的红色小鸟,奋不顾身的往绿色的肥猪的堡垒砸去,那种奇妙的感觉还真是令人感到很欢乐。而游戏的配乐同样充满了欢乐的感觉,轻松的节奏,欢快的风格。 源码下载

开启青龙 Ninja 扫码功能失效后修改成手动填写CK功能【修正Ninja拉库地址】

国内:进入容器docker exec -it qinglong bash #获取ninjagit clone -b main https://ghproxy.com/https://github.com/wjx0428/ninja.git /ql/ninja#安装cd /ql/ninja/backend && pnpm install cp .env.example .env

Android SurfaceFlinger——图形内存分配器(十一)

前面的文章中的图层合成器(HWC),这里我们接着看一下 SurfaceFlinger 中的另一个重要服务——图形内存分配器。 一、简介         android.hardware.graphics.allocator@2.0 是 Android 系统中硬件抽象层(HAL)的一个组件,专门用于图形内存的分配和管理。它是 SurfaceFlinger 在处理图形数据时所依赖的

【机器学习】半监督学习可以实现什么功能?

目录 一、什么是机器学习二、半监督学习算法介绍三、半监督学习算法的应用场景四、半监督学习可以实现什么功能? 一、什么是机器学习 机器学习是一种人工智能技术,它使计算机系统能够从数据中学习并做出预测或决策,而无需明确编程。它涉及到使用算法和统计模型来分析大量数据,识别其中的模式和关系,并利用这些信息来预测未来事件或做出决策。机器学习可以应用于各种领域,包括图像识别、自然语言