Android开发框架之自定义ZXing二维码扫描界面并解决取景框拉伸问题_Android

先给大家展示下效果图:

扫描内容是下面这张,二维码是用zxing库生成的

由于改了好几个类,还是去年的事都忘得差不多了,所以只能上这个类的代码了,主要就是改了这个CaptureActivity.java

package com.zxing.activity;
import java.io.IOException;
import java.util.Vector;
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Handler;
import android.os.Vibrator;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.widget.Toast;
import com.ericssonlabs.R;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.zxing.camera.CameraManager;
import com.zxing.decoding.CaptureActivityHandler;
import com.zxing.decoding.CaptureActivityHandler.DecodeCallback;
import com.zxing.decoding.InactivityTimer;
import com.zxing.view.ViewfinderView;
/**
* Initial the camera
* @author Ryan.Tang
* @modifier Lemon
* @use extends CaptureActivity并且在setContentView方法后调用init方法
*/
public abstract class CaptureActivity extends Activity implements Callback, DecodeCallback {
// private static final String TAG = "CaptureActivity";
protected Activity context;
protected SurfaceView surfaceView;
protected ViewfinderView viewfinderView;
/**初始化,必须在setContentView之后
* @param context
* @param viewfinderView
*/
protected void init(Activity context, SurfaceView surfaceView, ViewfinderView viewfinderView) {
this.context = context;
this.surfaceView = surfaceView;
this.viewfinderView = viewfinderView;
CameraManager.init(getApplication());
hasSurface = false;
inactivityTimer = new InactivityTimer(this);
}
private CaptureActivityHandler handler;
private boolean hasSurface;
private Vector<BarcodeFormat> decodeFormats;
private String characterSet;
private InactivityTimer inactivityTimer;
private MediaPlayer mediaPlayer;
private boolean playBeep;
private static final float BEEP_VOLUME = .f;
private boolean vibrate;
@Override
protected void onResume() {
super.onResume();
SurfaceHolder surfaceHolder = surfaceView.getHolder();
if (hasSurface) {
initCamera(surfaceHolder);
} else {
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
decodeFormats = null;
characterSet = null;
playBeep = true;
AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE);
if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
playBeep = false;
}
initBeepSound();
vibrate = true;
}
@Override
protected void onPause() {
super.onPause();
if (handler != null) {
handler.quitSynchronously();
handler = null;
}
CameraManager.get().closeDriver();
}
@Override
protected void onDestroy() {
inactivityTimer.shutdown();
super.onDestroy();
}
public static final String RESULT_QRCODE_STRING = "RESULT_QRCODE_STRING";
/**
* Handler scan result
* @param result
* @param barcode
*/
public void handleDecode(Result result, Bitmap barcode) {
inactivityTimer.onActivity();
playBeepSoundAndVibrate();
String resultString = result.getText();
//FIXME
if (resultString.equals("")) {
Toast.makeText(CaptureActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show();
}
setResult(RESULT_OK, new Intent().putExtra(RESULT_QRCODE_STRING, resultString));
finish();
}
private void initCamera(SurfaceHolder surfaceHolder) {
try {
CameraManager.get().openDriver(surfaceHolder);
} catch (IOException ioe) {
return;
} catch (RuntimeException e) {
return;
}
if (handler == null) {
handler = new CaptureActivityHandler(this, decodeFormats,
characterSet, viewfinderView, this);
}
}
@Override
public void drawViewfinder() {
viewfinderView.drawViewfinder();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (!hasSurface) {
hasSurface = true;
initCamera(holder);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
hasSurface = false;
}
public Handler getHandler() {
return handler;
}
private void initBeepSound() {
if (playBeep && mediaPlayer == null) {
// The volume on STREAM_SYSTEM is not adjustable, and users found it
// too loud,
// so we now play on the music stream.
setVolumeControlStream(AudioManager.STREAM_MUSIC);
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnCompletionListener(beepListener);
AssetFileDescriptor file = getResources().openRawResourceFd(
R.raw.beep);
try {
mediaPlayer.setDataSource(file.getFileDescriptor(),
file.getStartOffset(), file.getLength());
file.close();
mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
mediaPlayer.prepare();
} catch (IOException e) {
mediaPlayer = null;
}
}
}
private static final long VIBRATE_DURATION = L;
private void playBeepSoundAndVibrate() {
if (playBeep && mediaPlayer != null) {
mediaPlayer.start();
}
if (vibrate) {
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(VIBRATE_DURATION);
}
}
/**
* When the beep has finished playing, rewind to queue up another one.
*/
private final OnCompletionListener beepListener = new OnCompletionListener() {
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.seekTo();
}
};
} 

使用方法: 新建一个Activity继承CaptureActivity并且在setContentView方法后调用init方法即可。
示例:

CameraScanActivity.java

package zuo.biao.activity;
import zuo.biao.R;
import zuo.biao.library.interfaces.OnBottomDragListener;
import zuo.biao.util.ActivityUtil;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import com.zxing.activity.CaptureActivity;
import com.zxing.camera.CameraManager;
import com.zxing.view.ViewfinderView;
/**扫描二维码Activity
* @author Lemon
* @use 参考zuo.biao.library.ModelActivity
*/
public class CameraScanActivity extends CaptureActivity implements Callback, OnClickListener, OnBottomDragListener {
public static final String TAG = "CameraScanActivity";
//启动方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
/**启动这个Activity的Intent
* @param context
* @param title
* @return
*/
public static Intent createIntent(Context context) {
return new Intent(context, CameraScanActivity.class);
}
//启动方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_scan_activity);
init(this, (SurfaceView) findViewById(R.id.svCameraScan), (ViewfinderView) findViewById(R.id.vfvCameraScan));
//功能归类分区方法,必须调用<<<<<<<<<<
initView();
initData();
initListener();
//功能归类分区方法,必须调用>>>>>>>>>>
}
//UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
public void initView() {//必须调用
}
//UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
public void initData() {//必须调用
}
//data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//listener事件监听区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
public void initListener() {//必须调用
findViewById(R.id.tvCameraScanReturn).setOnClickListener(this);
findViewById(R.id.ivCameraScanReturn).setOnClickListener(this);
findViewById(R.id.ivCameraScanLight).setOnClickListener(this);
findViewById(R.id.ivCameraScanMyQRCode).setOnClickListener(this);
}
//系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
@Override
public void onDragBottom(boolean rightToLeft) {
if (rightToLeft) {
return;
}
finish();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tvCameraScanReturn:
case R.id.ivCameraScanReturn:
onDragBottom(false);
break;
case R.id.ivCameraScanLight:
switchLight(! isOpen);
break;
case R.id.ivCameraScanMyQRCode:
//
break;
default:
break;
}
}
private boolean isOpen = false;
/**打开或关闭闪关灯
* @param open
*/
private void switchLight(boolean open) {
if (open == isOpen) {
return;
}
isOpen = CameraManager.get().switchLight(open);
}
//类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//listener事件监听区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
} 

CameraScanActivity布局文件camera_scan_activity.xml

<?xml version="." encoding="utf-"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/activity_page" >
<SurfaceView
android:id="@+id/svCameraScan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<!-- 必须在最底层,且不能指定宽高,否则扫描读取很难实现 -->
<com.zxing.view.ViewfinderView
android:id="@+id/vfvCameraScan"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
style="@style/ll_vertical_match_match"
android:baselineAligned="false" >
<RelativeLayout
style="@style/topbar_bg"
android:background="@color/white_alpha" >
<TextView
android:id="@+id/tvCameraScanReturn"
style="@style/topbar_left_btn"
android:text=" " />
<TextView
style="@style/topbar_title"
android:layout_centerHorizontal="true"
android:text="扫一扫" />
</RelativeLayout>
<LinearLayout
style="@style/ll_vertical_match_match"
android:layout_gravity="center_horizontal"
android:layout_weight="" >
<TextView
style="@style/text_middle_white"
android:layout_margin="dp"
android:text="@string/camera_scan_remind" />
</LinearLayout>
<LinearLayout
style="@style/ll_horizontal_match_wrap"
android:layout_gravity="bottom"
android:background="@color/white_alpha"
android:gravity="center" >
<LinearLayout
style="@style/ll_vertical_wrap_wrap"
android:layout_margin="dp"
android:paddingBottom="dp"
android:paddingLeft="dp"
android:paddingRight="dp"
android:paddingTop="dp" >
<ImageView
android:id="@+id/ivCameraScanReturn"
style="@style/wrap_wrap"
android:background="@drawable/cilcle_gray_to_white"
android:padding="dp"
android:src="@drawable/back_black_light" />
<TextView
style="@style/text_small"
android:layout_marginTop="dp"
android:text="返回" />
</LinearLayout>
<LinearLayout
style="@style/ll_vertical_wrap_wrap"
android:layout_margin="dp"
android:paddingBottom="dp"
android:paddingLeft="dp"
android:paddingRight="dp"
android:paddingTop="dp" >
<ImageView
android:id="@+id/ivCameraScanLight"
style="@style/wrap_wrap"
android:background="@drawable/cilcle_gray_to_white"
android:padding="dp"
android:src="@drawable/flash_light" />
<TextView
style="@style/text_small"
android:layout_marginTop="dp"
android:text="开灯/关灯" />
</LinearLayout>
<LinearLayout
style="@style/ll_vertical_wrap_wrap"
android:layout_margin="dp"
android:paddingBottom="dp"
android:paddingLeft="dp"
android:paddingRight="dp"
android:paddingTop="dp" >
<ImageView
android:id="@+id/ivCameraScanMyQRCode"
style="@style/wrap_wrap"
android:background="@drawable/cilcle_gray_to_white"
android:padding="dp"
android:src="@drawable/qrcode" />
<TextView
style="@style/text_small"
android:layout_marginTop="dp"
android:text="我的名片" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</FrameLayout> 

布局文件因为使用了ZBLibrary中的一些style,color等,只有这个layout的话会出现一些错误。自己新建一个layout文件并把ViewfinderView放到最外层布局文件内就行了。当然下载好下面附上的源码就没这问题了。

对了,记得在AndroidManifest.xml中加上这些权限:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.FLASHLIGHT" />

附源码(含使用方法)

GitHub源码      https://github.com/TommyLemon/Android-ZBLibrary 

开源中国源码    http://git.oschina.net/Lemon19950301/Android-ZBLibrary

关于Android开发框架之自定义ZXing二维码扫描界面并解决取景框拉伸问题就给大家介绍到这里,以上内容有点长,希望大家能耐心看完,有任何问题欢迎给我留言,小编会及时回复大家的,在此也非常感谢大家对网站的支持!

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android
, zxing二维码
zxing拉伸
zxing 二维码拉伸、zxing 取景框大小、zxing 拉伸、zxing 图像拉伸、zxing 图片拉伸,以便于您获取更多的相关知识。

时间: 2024-07-28 22:56:56

Android开发框架之自定义ZXing二维码扫描界面并解决取景框拉伸问题_Android的相关文章

Android Zxing二维码扫描图片拉伸问题的解决方法

还是这个接手项目,二维码扫描集成的是zxing,扫描界面的图像有明显的拉伸变形. 这种问题,根据以往的经验,一般是x,y轴错位引起的,处理好x,y轴的问题,一般可以解决问题. 由于这个问题,之前有很多人遇到,并分享在网上了,所以,我这里也就不需要重复造轮子了. 这里看了一篇博客:Android Zxing二维码扫描图片拉伸,用了上面的办法, 成功的解决图片拉伸问题. 解决方法如下: 修改CameraConfigurationManager.Java里面的initFromCameraParamet

Android zxing二维码扫描 扫描框适应各种分辨率

在使用zxing二维码时,发现有时候出现拉伸的现象,不能很好的适应各种分辨率,经过测试,只要在CameraManager.java中,修改一下如下方法即可,代码如下: public synchronized Rect getFramingRect() { if (framingRect == null) { if (camera == null) { return null; } Point screenResolution = configManager.getScreenResolution

result-android开发遇到的关于Zxing二维码扫描结果怎样处理的问题

问题描述 android开发遇到的关于Zxing二维码扫描结果怎样处理的问题 如何把public void handleDecode(Result result, Bitmap barcode)得到的数据传递到一个未继承Activity 的类中 解决方案 直接在那个类中调用这个函数就可以了.

ZXing二维码扫描

一.  二维码 1.二维码名片 它是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的,在代码编制上巧妙地利用构成计算机内部逻辑基础的"0"."1"比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理.它具有条码技术的一些共性:每种码制有其特定的字符集:每个字符占有一定的宽度:具有一定的校验功能等.同时还具有对不同行的信息自动识别功能.及处理图形旋转变化等特

Android Zxing二维码扫描图片拉伸的解决方法

二维码扫描,Android Zxing图片拉伸解决. Zxing是google提供的二维码扫描工程 默认是横屏的  转换成竖屏后图片出现拉伸 这里提供解决办法: Zxing 修改 CameraConfigurationManager.Java文件的void initFromCameraParameters(Camera camera)方法 在Log.d(TAG, "Screen resolution: " + screenResolution);这句之后增加 Point screenR

Android基于google Zxing实现各类二维码扫描效果_Android

随着微信的到来,二维码越来越火爆,随处能看到二维码,比如商城里面,肯德基,餐厅等等,对于二维码扫描我们使用的是google的开源框架Zxing,我们可以去http://code.google.com/p/zxing/下载源码和Jar包,之前我项目中的二维码扫描功能只实现了扫描功能,其UI真的是其丑无比,一个好的应用软件,其UI界面也要被大众所接纳,不然人家就不会用你的软件啦,所以说应用软件功能和界面一样都很重要,例如微信,相信微信UI被很多应用软件所模仿,我也仿照微信扫描二维码效果进行模仿,虽然

Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果

转载请注明出处:http://blog.csdn.net/xiaanming/article/details/10163203 了解二维码这个东西还是从微信中,当时微信推出二维码扫描功能,自己感觉挺新颖的,从一张图片中扫一下竟然能直接加好友,不可思议啊,那时候还不了解二维码,呵呵,然后做项目的时候,老板说要加上二维码扫描功能,然后自己的屁颠屁颠的去百度,google啥的,发现很多朋友都有介绍二维码扫描的功能,然后我就跟着人家的介绍自己搞起了二维码扫描功能,跟着人家的帖子,很快我的项目就加入了扫描

Android基于google Zxing实现各类二维码扫描效果

随着微信的到来,二维码越来越火爆,随处能看到二维码,比如商城里面,肯德基,餐厅等等,对于二维码扫描我们使用的是google的开源框架Zxing,我们可以去http://code.google.com/p/zxing/下载源码和Jar包,之前我项目中的二维码扫描功能只实现了扫描功能,其UI真的是其丑无比,一个好的应用软件,其UI界面也要被大众所接纳,不然人家就不会用你的软件啦,所以说应用软件功能和界面一样都很重要,例如微信,相信微信UI被很多应用软件所模仿,我也仿照微信扫描二维码效果进行模仿,虽然

Android实现二维码扫描并登陆网页_Android

之前写过一个二维码扫描demo,用的Zxing的框架,点击下载,后续扫描二维码中出现一些问题,比如解决压缩图片,调整扫描窗口大小等等.后续单位要求做扫描登录实现,发现难点就是怎么知道你扫描的是这台电脑,后台必须获取到(后台技术的问题)然后把这个参数给我,再传递到后台,后台判断登录即可.这样自己扫描后直接传递个参数就可以实现登录了. 效果如下: 大概代码实现:扫描跳转: //扫描登录a case R.id.tv_more_qr: if (PventQuickClick.isFastDoubleCl