您好,欢迎访问一九零五行业门户网

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

先给大家展示下效果图:
扫描内容是下面这张,二维码是用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二维码扫描界面并解决取景框拉伸问题。
其它类似信息

推荐信息