先给大家展示下效果图:
扫描内容是下面这张,二维码是用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;@Overrideprotected 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;}@Overrideprotected void onPause() {super.onPause();if (handler != null) {handler.quitSynchronously();handler = null;}CameraManager.get().closeDriver();}@Overrideprotected 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();//FIXMEif (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);}}@Overridepublic void drawViewfinder() {viewfinderView.drawViewfinder(); }@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 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);}//启动方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>@Overrideprotected 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);}//系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<@Overridepublic void onDragBottom(boolean rightToLeft) {if (rightToLeft) {return;}finish();}@Overridepublic 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" ><SurfaceViewandroid:id="@+id/svCameraScan"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center" /><!-- 必须在最底层,且不能指定宽高,否则扫描读取很难实现 --><com.zxing.view.ViewfinderViewandroid:id="@+id/vfvCameraScan"android:layout_width="match_parent"android:layout_height="match_parent" /><LinearLayoutstyle="@style/ll_vertical_match_match"android:baselineAligned="false" ><RelativeLayoutstyle="@style/topbar_bg"android:background="@color/white_alpha" ><TextViewandroid:id="@+id/tvCameraScanReturn"style="@style/topbar_left_btn"android:text=" " /><TextViewstyle="@style/topbar_title"android:layout_centerHorizontal="true"android:text="扫一扫" /></RelativeLayout><LinearLayoutstyle="@style/ll_vertical_match_match"android:layout_gravity="center_horizontal"android:layout_weight="" ><TextViewstyle="@style/text_middle_white"android:layout_margin="dp"android:text="@string/camera_scan_remind" /></LinearLayout><LinearLayoutstyle="@style/ll_horizontal_match_wrap"android:layout_gravity="bottom"android:background="@color/white_alpha"android:gravity="center" ><LinearLayoutstyle="@style/ll_vertical_wrap_wrap"android:layout_margin="dp"android:paddingBottom="dp"android:paddingLeft="dp"android:paddingRight="dp"android:paddingTop="dp" ><ImageViewandroid:id="@+id/ivCameraScanReturn"style="@style/wrap_wrap"android:background="@drawable/cilcle_gray_to_white"android:padding="dp"android:src="@drawable/back_black_light" /><TextViewstyle="@style/text_small"android:layout_marginTop="dp"android:text="返回" /></LinearLayout><LinearLayoutstyle="@style/ll_vertical_wrap_wrap"android:layout_margin="dp"android:paddingBottom="dp"android:paddingLeft="dp"android:paddingRight="dp"android:paddingTop="dp" ><ImageViewandroid:id="@+id/ivCameraScanLight"style="@style/wrap_wrap"android:background="@drawable/cilcle_gray_to_white"android:padding="dp"android:src="@drawable/flash_light" /><TextViewstyle="@style/text_small"android:layout_marginTop="dp"android:text="开灯/关灯" /></LinearLayout><LinearLayoutstyle="@style/ll_vertical_wrap_wrap"android:layout_margin="dp"android:paddingBottom="dp"android:paddingLeft="dp"android:paddingRight="dp"android:paddingTop="dp" ><ImageViewandroid:id="@+id/ivCameraScanMyQRCode"style="@style/wrap_wrap"android:background="@drawable/cilcle_gray_to_white"android:padding="dp"android:src="@drawable/qrcode" /><TextViewstyle="@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二维码扫描界面并解决取景框拉伸问题就给大家介绍到这里,以上内容有点长,希望大家能耐心看完,有任何问题欢迎给我留言,小编会及时回复大家的,在此也非常感谢大家对武林网网站的支持!
新闻热点
疑难解答