Android二维码扫描
来源:互联网 发布:丁香园cto 知乎 编辑:程序博客网 时间:2024/06/06 09:52
本文详细说明怎么在Android端实现二维码扫描,只是讲述如何利用Google zxing进行二维码扫描,不涉及代码的深入研究,结果文章最后附有demo,demo可直接使用,觉得文章累赘可以直接拷demo中的包和类应用到自己的项目中使用
1.先将zxing.jar拷到libs文件夹并添加依赖到项目
2.将下面几个包跟类拷贝到项目中
3.扫描页逻辑跟界面
public class Sao1SaoActivity extends Activity implements Callback{ private SurfaceView surfaceView; private ViewfinderView viewfinderView; 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 = 0.10f; private boolean vibrate; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sao1sao); surfaceView = (SurfaceView) findViewById(R.id.preview_view); viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view); //ViewUtil.addTopView(getApplicationContext(), this, R.string.scan_card); CameraManager.init(getApplication()); hasSurface = false; inactivityTimer = new InactivityTimer(this); } @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(); } /** * 处理扫描结果 * * @param result * @param barcode */ public void handleDecode(Result result, Bitmap barcode) { inactivityTimer.onActivity(); playBeepSoundAndVibrate(); String resultString = result.getText(); if (resultString.equals("")) { Toast.makeText(Sao1SaoActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show(); Sao1SaoActivity.this.finish(); } else { Intent resultIntent = new Intent(); resultIntent.setClass(Sao1SaoActivity.this, Sao1SaoResultActivity.class); resultIntent.putExtra("result", resultString); ByteArrayOutputStream baos = new ByteArrayOutputStream(); barcode.compress(Bitmap.CompressFormat.PNG, 100, baos); byte[] bitmapByte = baos.toByteArray(); resultIntent.putExtra("bitmap", bitmapByte); startActivity(resultIntent); overridePendingTransition(R.anim.activity_in_from_rigth, R.anim.activity_out_to_scale); Sao1SaoActivity.this.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); } } @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 viewfinderView; } public Handler getHandler() { return handler; } public void drawViewfinder() { viewfinderView.drawViewfinder(); } /** * 初始化声音资源 */ 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 = 200L; /** * 响铃和震动 */ 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 MediaPlayer.OnCompletionListener beepListener = new MediaPlayer.OnCompletionListener() { public void onCompletion(MediaPlayer mediaPlayer) { mediaPlayer.seekTo(0); } };}
其中:
/** * 处理扫描结果 * * @param result * @param barcode */ public void handleDecode(Result result, Bitmap barcode) { inactivityTimer.onActivity(); playBeepSoundAndVibrate(); String resultString = result.getText(); if (resultString.equals("")) { Toast.makeText(Sao1SaoActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show(); Sao1SaoActivity.this.finish(); } else { Intent resultIntent = new Intent(); resultIntent.setClass(Sao1SaoActivity.this, Sao1SaoResultActivity.class); resultIntent.putExtra("result", resultString); ByteArrayOutputStream baos = new ByteArrayOutputStream(); barcode.compress(Bitmap.CompressFormat.PNG, 100, baos); byte[] bitmapByte = baos.toByteArray(); resultIntent.putExtra("bitmap", bitmapByte); startActivity(resultIntent); overridePendingTransition(R.anim.activity_in_from_rigth, R.anim.activity_out_to_scale); Sao1SaoActivity.this.finish(); } }
这个方法是处理扫描结果的
playBeepSoundAndVibrate();//这个方法是为了扫描出结果时震动和响铃
然后下面是执行扫描结果,我这里是把数据携带然后跳转到另一个界面、但是有个注意的是bundle和Intent.putExtra是不能传递大于40kb的图片的,所以解决办法是吧bitmap转换成byte数组然后再把byte数据传递过去。
扫描界面布局为:
<?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.sjr.saomiao.view.ViewfinderView android:id="@+id/viewfinder_view" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <include android:id="@+id/include1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" layout="@layout/activity_sao1sao_title" /> </RelativeLayout></FrameLayout>
扫描结果我将它显示成了一个edittext
public class Sao1SaoResultActivity extends Activity { private EditText etSao1SaoResult; private Button btnBack; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sao1sao_result); etSao1SaoResult = (EditText) findViewById(R.id.et_sao1sao_result); btnBack = (Button) findViewById(R.id.btn_back); String result = getIntent().getStringExtra("result"); etSao1SaoResult.setText(result); btnBack.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Sao1SaoResultActivity.this.finish(); } }); }
然后这样就完成了一个扫描的demo,下面是说明一些参数比如扫描匡大小和颜色之类的ui
扫描匡的四个角颜色是在ViewfinderView这个类里面,这个类前面已经拷过项目里面了,
还有一些框下面的文字之类的设置也是在这个类,直接进这个类去改参数就可以了。
扫描匡的大小是在CameraManager这个类里面
private static final int MIN_FRAME_WIDTH = 480;
private static final int MIN_FRAME_HEIGHT = 480;
private static final int MAX_FRAME_WIDTH = 720;
private static final int MAX_FRAME_HEIGHT = 600;
这四个参数就是设置匡的大小
上面这些就已经完成一个二维码扫描的业务逻辑了
结果如下我拿来扫描了一下微信:
完整源码下载地址:
http://download.csdn.net/detail/lxzmmd/9506920
3 0
- android 扫描二维码 生产二维码
- Android 二维码扫描
- Android二维码扫描
- android二维码扫描 ZBar
- android 二维码扫描开发
- Android "QR二维码扫描"
- cocos2dx android 二维码扫描
- android 二维码 条形码扫描
- android二维码扫描
- Android扫描二维码
- Android二维码扫描、生成
- android 二维码 扫描
- Android二维码扫描
- Android二维码扫描
- android二维码的扫描
- android二维码扫描
- Android二维码扫描开发
- Android - BGAQRCode 扫描二维码
- DVFS User Guide
- NYOJ 19 擅长排列的小明
- 卷积神经网络
- NYOJ 8 一种排序
- UISegmentedControl使用方法
- Android二维码扫描
- 忘记root密码怎么办?
- 利用种子填充法对二值图像进行连通域标记
- Android_Retrofit_初学记录
- Java程序员必须掌握的8大排序算法
- js对象无法当成参数传递
- CLOSE_WAIT问题
- 关于IOS AppIcon 的规范
- Linux下如何防止僵尸进程的出现