很多朋友没有做过二维码扫描方面的可能会觉得比较复杂,先定义就是不好下手,但是自己仔细写一下其实也好,毕竟网上类似二维码扫描的特别多,好人也很多。下面的我就来基于zbar集成的一个二维码扫描。
首先就是扫面的布局的绘制,这里我就简单说明一下,里面就一个扫描的view,然后就加了一个闪光灯的按钮,点击可以打开闪光灯的,然后就是基本按钮了,我的二维码。这里可以点击去自己想去的页面,这里呢我就没有写了。再一个就是返回,现看看xml代码先
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<SurfaceView
android:id="@+id/preview_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.leo.zbardemo.zbar.view.ViewfinderView
android:id="@+id/viewfinder_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#00000000" />
<RelativeLayout
android:id="@+id/rl_title"
android:layout_width="fill_parent"
android:layout_height="42dp"
android:layout_alignParentTop="true"
android:background="#000000">
<ImageView
android:id="@+id/iv_title_back"
android:layout_width="64dp"
android:layout_height="44dp"
android:layout_centerVertical="true"
android:background="@drawable/top_backup"
android:contentDescription="@null"
/>
<TextView
android:id="@+id/tv_title_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:singleLine="true"
android:text="二维码扫描"
android:textColor="#ffffff"
android:textSize="18sp" />
<ImageView
android:id="@+id/iv_flashlight"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:layout_centerVertical="true"
android:src="@drawable/icon_light" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/my_qr_code"
android:layout_width="wrap_content"
android:layout_height="54dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp">
<ImageView
android:id="@+id/album"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_centerHorizontal="true"
android:src="@drawable/icon_erweima" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/album"
android:layout_centerHorizontal="true"
android:text="我的二维码"
android:textColor="#fff"
android:textSize="12sp" />
</RelativeLayout>
</RelativeLayout>
</FrameLayout>
</FrameLayout>
接下来就是对于那个xml页面的基本操作,比如声音啊,然后recorder的处理,扫描data的分析和处理等,最重要的就是返回个自己的页面的操作。
package com.leo.zbardemo.zbar.client;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.leo.zbardemo.R;
import com.leo.zbardemo.zbar.camera.CameraManager;
import com.leo.zbardemo.zbar.decode.CaptureActivityHandler;
import com.leo.zbardemo.zbar.decode.InactivityTimer;
import com.leo.zbardemo.zbar.view.ViewfinderView;
import java.io.IOException;
public class CaptureActivity extends AppCompatActivity implements SurfaceHolder.Callback, View.OnClickListener {
private InactivityTimer inactivityTimer;
private CaptureActivityHandler handler;
private MediaPlayer mediaPlayer;
private boolean playBeep;
private boolean vibrate;
private boolean flag = true;
private boolean hasSurface = false;
private ViewfinderView viewfinderView;
private ImageView iv_title_back;
private ImageView iv_flashlight;
private RelativeLayout my_qr_code;
private ScreenOffReceiver mScreenOffReceiver = new ScreenOffReceiver();
;
private static final float BEEP_VOLUME = 0.20f;
private static final long VIBRATE_DURATION = 200L;
private final OnCompletionListener beepListener = new OnCompletionListener() {
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.seekTo(0);
}
};
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 void initCamera(SurfaceHolder surfaceHolder) {
try {
CameraManager.get().openDriver(surfaceHolder);
} catch (IOException ioe) {
return;
} catch (RuntimeException e) {
return;
}
if (handler == null) {
handler = new CaptureActivityHandler(this);
}
}
private void playBeepSoundAndVibrate() {
if (playBeep && mediaPlayer != null) {
mediaPlayer.start();
}
if (vibrate) {
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(VIBRATE_DURATION);
}
}
public ViewfinderView getViewfinderView() {
return viewfinderView;
}
public Handler getHandler() {
return handler;
}
public void drawViewfinder() {
viewfinderView.drawViewfinder();
}
public void handleDecode(String result) {
inactivityTimer.onActivity();
playBeepSoundAndVibrate();
Intent intent = new Intent();
intent.putExtra("result", result);
Message message = Message.obtain(getHandler(), R.id.return_scan_result, intent);
message.sendToTarget();
}
public void light() {
if (this.flag) {
CameraManager.get().openLight();
this.flag = false;
this.iv_flashlight.setImageDrawable(getResources().getDrawable(R.drawable.icon_light_hover));
return;
}
CameraManager.get().offLight();
this.flag = true;
this.iv_flashlight.setImageDrawable(getResources().getDrawable(R.drawable.icon_light));
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.capture);
CameraManager.init(getApplication());
this.viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
this.iv_flashlight = (ImageView) findViewById(R.id.iv_flashlight);
this.my_qr_code = (RelativeLayout) findViewById(R.id.my_qr_code);
this.iv_flashlight.setOnClickListener(this);
this.iv_title_back = (ImageView) findViewById(R.id.iv_title_back);
this.iv_title_back.setOnClickListener(this);
this.my_qr_code.setOnClickListener(this);
this.hasSurface = false;
this.inactivityTimer = new InactivityTimer(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(this.mScreenOffReceiver, intentFilter);
}
@Override
protected void onPause() {
if (handler != null) {
handler.quitSynchronously();
handler = null;
}
CameraManager.get().offLight();
inactivityTimer.onPause();
CameraManager.get().closeDriver();
if (!hasSurface) {
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
surfaceHolder.removeCallback(this);
}
super.onPause();
}
@SuppressWarnings("deprecation")
@Override
protected void onResume() {
super.onResume();
handler = null;
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
if (hasSurface) {
initCamera(surfaceHolder);
} else {
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
playBeep = true;
AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE);
if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
playBeep = false;
}
initBeepSound();
inactivityTimer.onResume();
vibrate = true;
}
@Override
protected void onDestroy() {
inactivityTimer.shutdown();
unregisterReceiver(this.mScreenOffReceiver);
super.onDestroy();
}
@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;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.iv_flashlight:
light();
break;
case R.id.iv_title_back:
this.finish();
break;
case R.id.my_qr_code:
Toast.makeText(this, "我的二维码", Toast.LENGTH_SHORT).show();
break;
}
}
private class ScreenOffReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context arg0, Intent arg1) {
Log.d("CaptureActivity", "CaptureActivity receive screen off command ++");
CaptureActivity.this.finish();
}
}
}
我采用的是StartActivityForResult的跳转,然后在OnActivityResult里面的获取数据和分析数据,也就是扫描得到的东西。
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.tv_click:
Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
startActivityForResult(intent, 1234);
break;
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1234 && resultCode == RESULT_OK) {
Bundle bundle = data.getExtras();
//显示扫描到的内容
String content = bundle.getString("result");
Toast.makeText(this, content, Toast.LENGTH_SHORT).show();
}
}
剩下的也就是jar包和so库了,so库建议放在armeabi-v7a这个文件夹下面。