前言:
多年之前接触过zxing实现二维码,没想到今日项目中再此使用竟然使用的还是zxing,百度之,竟是如此牛的玩意。
当然,项目中我们也许只会用到二维码的扫描和生成两个功能,所以不必下载完整的jar包,使用简化版的即可,下文可见。
这篇文章讲述:
1、如果快速在项目中集成zxing,实现扫描和生成二维码功能
2、根据项目需求去修改源码实现我们的要求并进行优化
一、快速集成zxing二维码
1、下载库文件 :http://xiazai.jb51.net/201611/yuanma/ZXingBarCode_jb51.zip ,
下载完成后可以看到:
我们从这些文件中拷贝需要的到自己的项目中,下面开始:
①、res 目录下 : raw文件夹 整个复制到个人项目相对位置
②、res --> values目录下:IDs.xml文件中的内容全部复制到个人项目相对位置,个人项目没有则直接复制文件到相对位置
③、res --> values目录下:colors.xml文件中的内容全部复制到个人项目的相对位置
④、res --> layout目录下:camera.xml 布局文件复制到个人项目相对位置
⑤、res --> drawable_mdpi 目录下:navbar.9.png图片复制到个人项目相对位置,这张图片是标题栏背景图片,这里建议先改成navbar.png 不要使用.9图片
⑥、libs目录下:zxing.jar文件复制到个人项目相对位置,并且右键点击as library
⑦、src --> com目录下:zxing 文件夹复制到个人项目相对位置 ,会报错,修改R的目录结构即可
⑧、AndroIDManifest.xml文件中 添加 (二维码扫描activity,这个需要后面自己去修改,用于实现自己的要求)
<activity androID:name="com.zxing.activity.CaptureActivity"/>
⑨、AndroIDManifest.xml文件中 添加权限
<uses-permission androID:name="androID.permission.CAMERA" /> <uses-permission androID:name="androID.permission.VIBRATE" /> <uses-permission androID:name="androID.permission.READ_EXTERNAL_STORAGE" /> <uses-permission androID:name="androID.permission.MOUNT_UNMOUNT_fileSYstemS" /> <uses-permission androID:name="androID.permission.WRITE_EXTERNAL_STORAGE" />
2、准备工作完成了,下面开始写demo
现在需求是一个主界面MainActivity.java 里面有两个按钮,分别跳转 生成二维码界面和 扫描二维码界面
然后分别开始写两个activity功能的实现:
①、 生成二维码
先写布局文件 ,一个图片 , 一个开始生成按钮 , 一个输入框(二维码需要根据文本信息生成,没有文本信息无法生成)
activity_create.xml
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" xmlns:tools="http://schemas.androID.com/tools" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:orIEntation="vertical" tools:context="com.maiji.zxingdemo.CreateActivity"> <ImageVIEw androID:ID="@+ID/create_img" androID:layout_wIDth="300dp" androID:layout_height="300dp" androID:scaleType="fitXY" androID:layout_gravity="center_horizontal" /> <button androID:ID="@+ID/create_btn" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_gravity="center_horizontal" androID:text="开始生成二维码" /> <EditText androID:ID="@+ID/create_edit" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" /></linearLayout>
activity代码: 代码比较简单 ,不在此解释了
private ImageVIEw create_img; private button create_btn; private EditText create_edit; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_create); initVIEw(); initEvent(); } private voID initEvent() { create_btn.setonClickListener(this); } private voID initVIEw() { create_img = (ImageVIEw) findVIEwByID(R.ID.create_img); create_btn = (button) findVIEwByID(R.ID.create_btn); create_edit = (EditText) findVIEwByID(R.ID.create_edit); } @OverrIDe public voID onClick(VIEw v) { switch (v.getID()){ case R.ID.create_btn: String content = "" ; if (create_edit.getText().toString().equals("")){ Toast.makeText(this,"请输入二维码信息",Toast.LENGTH_SHORT).show(); return; } content = create_edit.getText().toString(); try { //生成二维码图片,第一个参数是二维码的内容,第二个参数是正方形图片的边长,单位是像素 Bitmap qrcodeBitmap = EnCodingHandler.createQRCode(content,800); if (qrcodeBitmap!=null) { create_img.setimageBitmap(qrcodeBitmap); }else{ Toast.makeText(this,"生成二维码失败",Toast.LENGTH_SHORT).show(); } } catch (Exception e) { // Todo auto-generated catch block e.printstacktrace(); } break; } } public byte[] Bitmap2Bytes(Bitmap bm) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.PNG,100,baos); return baos.toByteArray(); }
效果图:
②、扫描二维码
这个就更简单了,只需要打开一个zxing提供的activity 然后获取到扫描得到的字符串即可
看ScanActivity(扫描Activity)的关键代码
private TextVIEw zxing_content;@OverrIDeprotected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_scan); zxing_content = (TextVIEw) findVIEwByID(R.ID.zxing_content); Intent startScan = new Intent(this,CaptureActivity.class); startActivityForResult(startScan,0); //实际打开了一个zxing提供给我们的扫描activity,当然我们后面会对这个activity进行一些优化修改}/** * 扫一扫,成功后返回值进行判断 */@OverrIDepublic voID onActivityResult(int requestCode,int resultCode,Intent data) { super.onActivityResult(requestCode,resultCode,data); if (resultCode == -1) { String result = data.getExtras().getString("result"); zxing_content.setText(result); //显示扫描二维码得到的数据 }}
布局文件:
<?xml version="1.0" enCoding="utf-8"?><relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" xmlns:tools="http://schemas.androID.com/tools" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" tools:context="com.maiji.zxingdemo.ScanActivity"> <TextVIEw androID:ID="@+ID/zxing_content" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_centerInParent="true" androID:textSize="30sp" /></relativeLayout>
效果图:
二、修改源码,实现项目的需求
1、修改扫描二维码的界面
对应的是 zxing-->activity-->CaptureActivity.java ,布局文件为 camera.xml
所以修改界面只需要在 camera.xml文件中修改即可。
无非就是把原来的“CANCEL”取消按钮去掉,把顶部的标题栏换一下。
布局里面有一个 <SurfaceVIEw>控件 用于显示相机拍出的画面预览,这里可以根据需求改是全界面显示还是显示局部
<com.zxing.vIEw.VIEwfinderVIEw>控件,即扫描框,默认的是宽高比1:1.5,实际需要修改宽高,在下面介绍
2、修改扫描框的宽高
第1步 *** 作做完之后会发现,我们没法修改扫描框的宽高。
修改扫描框宽高很简单,找到 zxing-->camera-->CameraManager.java 文件
这里较为顶部的代码中看到:
private static final int MIN_FRAME_WIDTH = 240; private static final int MIN_FRAME_HEIGHT = 240; private static final int MAX_FRAME_WIDTH = 480; private static final int MAX_FRAME_HEIGHT = 480;
这四个属性的值即扫描框的宽高,然后可以根据需求直接修改,当然这个值在不同分辨率的设备上宽高不一致 , 有需要的话可以进行一下单位转换
public static int Dp2Px( Context context,float dp) { final float scale = context.getResources().getdisplayMetrics().density; return (int) (dp * scale + 0.5f); }
效果图: 我修改了扫描框的最小最大宽高分别一致,并且载camera.xml布局中删去了“CANCEL”取消按钮
3、给扫描框添加文字提示
看一下微信的扫描界面,会发现扫描框下面有一段文字提示。 那么我们这里没有,需要添加
找到zxing-->vIEw-->VIEwfindervIEw.java
这里是自定义扫描框的类
找到代码:
canvas.drawRect(frame.left + 2,mIDdle - 1,frame.right - 1,mIDdle + 2,paint); Collection<ResultPoint> currentPossible = possibleResultPoints;
在这两行代码之间我们画上文字提示
canvas.drawRect(frame.left + 2,paint); TextPaint textPaint = new TextPaint(); textPaint.setARGB(0xFF,0xFF,0xFF); //字体颜色 textPaint.setTextSize(32); //字体大小 textPaint.setAntiAlias(true); //设置抗锯齿,否则字迹会很模糊 StaticLayout layout = new StaticLayout("将二维码放入框内,即可自动扫描",textPaint,frame.right-frame.left,Layout.Alignment.AliGN_norMAL,1.0F,0.0F,true); canvas.translate(frame.left+5,(float) (frame.bottom + (float)30)); //绘制起始位置 layout.draw(canvas); Collection<ResultPoint> currentPossible = possibleResultPoints;
然后在看下扫描界面效果图:
4、解决扫描界面相机预览拉伸变形问题
实现了上面几步的优化,仔细的同学可能会发现,如果我们给SurfaceVIEw设置全屏显示(可以看到的相机画面很多),会发现相机拍摄出来的预览图有些拉伸变形
原因:zxing横屏变竖屏之后,Camera的代码还是采用的横屏代码设置的参数
优化方法:找到 zxing-->camera--> CameraConfigurationManager.java
initFromCameraParameters方法中,在 Log.d(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 = getCameraResolution(parameters,screenResolution);更改为
cameraResolution = getCameraResolution(parameters,screenResolutionForCamera);
完成之后,在进行扫描 *** 作,这时候相机拍出来的预览界面就正常显示,不再有拉伸变形问题。
至此便给项目引入了一个可以使用的二维码模块功能了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android项目实战(二十八):使用Zxing实现二维码及优化实例全部内容,希望文章能够帮你解决Android项目实战(二十八):使用Zxing实现二维码及优化实例所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)