本文实例讲述了AndroID开发实现模仿360二维码扫描功能的方法。分享给大家供大家参考,具体如下:
一、效果图:
二、框架搭建
1、首先,下载最新zxing开源项目。 下载地址:http://code.google.com/p/zxing/
或 点击此处本站下载。
2、分析项目结构,明确扫描框架需求。在zxing中,有很多其他的功能,项目结构比较复杂;针对二维码QRCode扫描,我们需要几个包:
(1)com.Google.zxing.clIEnt.androID.Camera 基于Camera调用以及参数配置,核心包
(2)DecodeFormatManager、DecodeThread、DecodeHandler 基于解码格式、解码线程、解码结果处理的解码类
(3)VIEwfinderVIEw、VIEwfinderResultPointCallBack 基于取景框视图定义的VIEw类
(4)CaptureActivity、CaptureActivityHandler 基于扫描Activity以及扫描结果处理的Capture类
(5)InactivityTimer、BeepManager、FinishListener 基于休眠、声音、退出的辅助管理类
(6)Intents、IntentSource、PrefrencesActivity 基于常量存储的常量类
3、新建工程,添加如下权限permission:
<uses-permission androID:name="androID.permission.CAMERA"/><uses-permission androID:name="androID.permission.INTERNET" /><uses-permission androID:name="androID.permission.VIBRATE" /><uses-permission androID:name="androID.permission.FLASHliGHT" />
4、 添加core.jar文件,并Buildpath;将上述类或包加入工程后,会报一系列错误,原因有几点:
(1)资源文件缺乏,将zxing下需要的资源文件copy到新工程下
(2)版本兼容问题,zxing下很多技术都是使用4.0版本及以上,集成到低版本之后,须做相应改动,详情参照项目源码
(3)包结构引用问题,需要重新导入包引用
5、最后框架
三、具体实现
1、创建MainActivity用于跳转到扫描页面
/** * 二维码扫描 * @Project App_ZXing * @Package com.androID.scan * @author chenlin * @version 1.0 * @Date 2014年3月6日 */public class MainActivity extends Activity { private button mBtnScan; private button mBtnBack; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); mBtnBack = (button) findVIEwByID(R.ID.btn_back); mBtnBack.setVisibility(VIEw.GONE); mBtnScan = (button) findVIEwByID(R.ID.btn_scan); mBtnScan.setonClickListener(new VIEw.OnClickListener() { @OverrIDe public voID onClick(VIEw v) { startActivity(new Intent(MainActivity.this,ScanActivity.class)); } }); }}
布局文件
<?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" > <button androID:ID="@+ID/btn_scan" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_centerInParent="true" androID:textcolor="@color/white" androID:padding="20dp" androID:background="@drawable/btn_scan_result" androID:text="扫一扫" /> <include androID:layout_wIDth="fill_parent" androID:layout_height="wrap_content" androID:layout_alignParenttop="true" layout="@layout/activity_scan_Title" /></relativeLayout>
2、扫描页面
/** * 条形码扫描 * * @Project App_ZXing * @Package com.androID.scan * @author chenlin * @version 1.0 * @Date 2014年3月6日 */public class ScanActivity extends Activity implements Callback { private static final float BEEP_VolUME = 0.10f; protected static final String RESulT_TEXT = "result"; protected static final String RESulT_BITMAP = "bitmap"; /** 扫描界面 */ private SurfaceVIEw mSurfaceVIEw; /** 自定义的VIEw,就是我们看见的拍摄时中间的框框了 */ private VIEwfinderVIEw mFindVIEw; /** 解码处理类,负责调用另外的线程进行解码。 */ private CaptureActivityHandler mHandler; /** 判断是否创建了SurfaceVIEw */ private boolean hasSurface; /** decodeFormats 条形码,二维码等的集合 */ private Vector<barcodeFormat> mDecodeFormats; /** 字符编码 */ private String characterSet; /** 定时器 */ private InactivityTimer inactivityTimer; /** 媒体播放器 */ private MediaPlayer mediaPlayer; /** 是否播放声音 */ private boolean playBeep; /** 是否震动 */ private boolean vibrate; @OverrIDe public voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_scan); init(); } /** * 初始化 */ private voID init() { mSurfaceVIEw = (SurfaceVIEw) findVIEwByID(R.ID.prevIEw_vIEw); mFindVIEw = (VIEwfinderVIEw) findVIEwByID(R.ID.vIEwfinder_vIEw); CameraManager.init(getApplication()); hasSurface = false; inactivityTimer = new InactivityTimer(this); } /** * 暂停后恢复时处理内容 */ @SuppressWarnings("all") @OverrIDe protected voID onResume() { super.onResume(); // 先重新获得holder SurfaceHolder surfaceHolder = mSurfaceVIEw.getHolder(); if (hasSurface) { initCamera(surfaceHolder); } else { surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } mDecodeFormats = 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 (mHandler != null) { mHandler.quitSynchronously(); mHandler = null; } // 关闭摄像头信息 CameraManager.get().closeDriver(); } @OverrIDe protected voID onDestroy() { // 关闭定时器 inactivityTimer.shutdown(); super.onDestroy(); } /** * 处理扫描结果 * * @param result * @param barcode */ public voID handleDecode(Result result,Bitmap barcode) { // 添加定时器 inactivityTimer.onActivity(); // 响铃和震动 playBeepSoundAndVibrate(); String resultString = result.getText(); if (TextUtils.isEmpty(resultString)) { ToastUtil.show(this,"扫描失败"); ScanActivity.this.finish(); } else { //扫描完成后传递结果 Intent resultIntent = new Intent(); resultIntent.setClass(ScanActivity.this,ScanResultActivity.class); resultIntent.putExtra(RESulT_TEXT,resultString); ByteArrayOutputStream baos = new ByteArrayOutputStream(); barcode.compress(Bitmap.CompressFormat.PNG,100,baos); byte[] bitmapByte = baos.toByteArray(); resultIntent.putExtra(RESulT_BITMAP,bitmapByte); startActivity(resultIntent); overrIDePendingTransition(R.anim.activity_in_from_rigth,R.anim.activity_out_to_scale); ScanActivity.this.finish(); } } private voID initCamera(SurfaceHolder surfaceHolder) { try { CameraManager.get().openDriver(surfaceHolder); } catch (IOException ioe) { return; } catch (RuntimeException e) { return; } if (mHandler == null) { mHandler = new CaptureActivityHandler(this,mDecodeFormats,characterSet); } } @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 VIEwfinderVIEw getVIEwfinderVIEw() { return mFindVIEw; } public Handler getHandler() { return mHandler; } public voID drawVIEwfinder() { mFindVIEw.drawVIEwfinder(); } /** * 初始化声音资源 */ private voID initBeepSound() { // 如果要播放声音并且没有播放器时 if (playBeep && mediaPlayer == null) { // 设置声道流格式为音乐 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 = 200L; /** * 响铃和震动 */ private voID playBeepSoundAndVibrate() { if (playBeep && mediaPlayer != null) { mediaPlayer.start(); } if (vibrate) { Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE); // 震动一次 vibrator.vibrate(VIBRATE_DURATION); // 第一个参数,指代一个震动的频率数组。每两个为一组,每组的第一个为等待时间,第二个为震动时间。 // 比如 [2000,500,400],会先等待2000毫秒,震动500,再等待100,震动400 // 第二个参数,repest指代从 第几个索引(第一个数组参数) 的位置开始循环震动。 // 会一直保持循环,我们需要用 vibrator.cancel()主动终止 // vibrator.vibrate(new long[]{300,500},0); } } /** * 注册事件。当播放完毕一次后,重新指向流文件的开头,以准备下次播放。 */ private final MediaPlayer.OnCompletionListener beepListener = new MediaPlayer.OnCompletionListener() { public voID onCompletion(MediaPlayer mediaPlayer) { mediaPlayer.seekTo(0); } };}
布局文件
<?xml version="1.0" enCoding="utf-8"?><FrameLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" > <relativeLayout androID:layout_wIDth="match_parent" androID:layout_height="match_parent" > <SurfaceVIEw androID:ID="@+ID/prevIEw_vIEw" androID:layout_wIDth="fill_parent" androID:layout_height="fill_parent" androID:layout_gravity="center" /> <com.androID.scan.vIEw.VIEwfinderVIEw androID:ID="@+ID/vIEwfinder_vIEw" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" /> <include androID:layout_wIDth="fill_parent" androID:layout_height="wrap_content" androID:layout_alignParenttop="true" layout="@layout/activity_scan_Title" /> </relativeLayout></FrameLayout>
3、结果页面
/** * * @Project App_ZXing * @Package com.androID.scan * @author chenlin * @version 1.0 * @Date 2014年3月6日 * @Note Todo */public class ScanResultActivity extends Activity { private EditText mEtScan; private button mBtnBack; private button mBtncopy; private ImageVIEw mImageVIEw; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_scan_result); initVIEws(); init(); } private voID init() { final String result = getIntent().getStringExtra(ScanActivity.RESulT_TEXT); mEtScan.setText(result); final ClipboardManager cm = (ClipboardManager) getSystemService(CliPBOARD_SERVICE); mBtnBack.setonClickListener(new VIEw.OnClickListener() { @OverrIDe public voID onClick(VIEw v) { ScanResultActivity.this.finish(); } }); mBtncopy.setonClickListener(new OnClickListener() { @OverrIDe public voID onClick(VIEw v) { if (result!=null) { ClipData myClip = ClipData.newPlainText("text",result); cm.setPrimaryClip(myClip); } } }); //设置图片信息 byte[] imgByte = getIntent().getByteArrayExtra(ScanActivity.RESulT_BITMAP); if (imgByte != null) { Drawable drawable = BitmapUtil.byte2Drawable(imgByte); if (drawable != null) { mImageVIEw.setimageDrawable(drawable); } } } // public voID paste(VIEw vIEw){ // ClipData abc = myClipboard.getPrimaryClip(); // ClipData.Item item = abc.getItemAt(0); // String text = item.getText().toString(); // pasteFIEld.setText(text); // Toast.makeText(getApplicationContext(),"Text Pasted",// Toast.LENGTH_SHORT).show(); // } private voID initVIEws() { mEtScan = (EditText) findVIEwByID(R.ID.et_scan_result); mBtnBack = (button) findVIEwByID(R.ID.btn_back); mBtncopy = (button) findVIEwByID(R.ID.btn_copy); }}
四、代码下载
完整实例代码点击此处本站下载。
PS:这里再为大家推荐一款二维码在线生成工具供大家参考使用:
在线生成二维码工具(加强版)
http://tools.jb51.net/transcoding/jb51qrcode
更多关于AndroID相关内容感兴趣的读者可查看本站专题:《Android开发入门与进阶教程》、《Android数据库 *** 作技巧总结》、《Android编程之activity *** 作技巧总结》、《Android文件 *** 作技巧汇总》、《Android资源 *** 作技巧汇总》、《Android视图View技巧总结》及《Android控件用法总结》
希望本文所述对大家AndroID程序设计有所帮助。
总结以上是内存溢出为你收集整理的Android开发实现模仿360二维码扫描功能实例详解全部内容,希望文章能够帮你解决Android开发实现模仿360二维码扫描功能实例详解所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)