Android开发之利用ZXing库实现二维码的扫描

2017-04-26 11:41

在上一篇文章中我们介绍了二维码的生成,那么在生成一个二维码之后又怎么去对这个已经生成的二维码进行扫描呢?带着这个问题我们接下来就去一步一步的实现这个功能。
首先来介绍一下思路:要想实现这个扫描二维码的功能,那么首先就需要去打开相机,利用相机去对已经生成的二维码进行扫描,获取到扫描之后的信息然后回传给当前的activity;那么怎么去回传这个扫描获取到的信息呢?在调用相机的时候又怎么去识别这个生成的二维码呢?然后对获取到的信息有怎么去解析呢?带着这些问题我们来一步步的实现这个功能。
引用ZXing库在创建工程的时候就应该完成这一步骤
第一步:调用系统相机,实现扫描
第二步:获取扫描的数据返回
第三步:解析返回的数据
一:
因为涉及到后面的地方需要有数据的回传,所以这里在调用启动activity的时候使用startActivityForResult方法;其中需要跳转到的activity为我们自己定义的activity,在这个 activity中需要我们处理的东西有很多,我们来一步步的看,首先是布局文件,先来看看代码
这里写图片描述
其中SurfaceView是为这个扫描提供一个画布,作为一个载体,第二个是ZXing库提供的扫描的控件,然后来继续看看代码中是怎么实现的?
先贴上代码再来讲解
public final class CaptureActivity extends Activity implements Callback {
private static final long VIBRATE_DURATION = 200L;

private CaptureActivityHandler handler;//系统提供的扫描消息的handler
private ViewfinderView viewfinderView;
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;

public ViewfinderView getViewfinderView() {
    return viewfinderView;
}
public Handler getHandler() {
    return handler;
}

public void drawViewfinder() {
    viewfinderView.drawViewfinder();
}
/**
 * OnCreate中初始化一些辅助类,如InactivityTimer(休眠)、Beep(声音)以及AmbientLight(闪光灯)
 */
@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    // 保持Activity处于唤醒状态
    Window window = getWindow();
    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.capture);

    CameraManager.init(getApplication());
    viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);

    hasSurface = false;
    inactivityTimer = new InactivityTimer(this);
}
@Override
protected void onResume() {
    super.onResume();
    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);
    }
    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();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
    if (!hasSurface) {
        hasSurface = true;
        initCamera(holder);
    }
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    hasSurface = false;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
}
/**
 * 扫描成功,处理反馈信息
 */
public void handleDecode(Result rawResult, Bitmap barcode) {
    inactivityTimer.onActivity();
    // 这里处理解码完成后的结果,此处将参数回传到Activity处理
    if (barcode != null) {
        playBeepSoundAndVibrate();
        Intent intent = getIntent();
        setResult(RESULT_OK, intent);
        finish();
    }
}
/**
 * 初始化Camera
 */
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);
    }
}
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 playBeepSoundAndVibrate() {
    if (playBeep && mediaPlayer != null) {
        mediaPlayer.start();
    }
    if (vibrate) {
        Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
        vibrator.vibrate(VIBRATE_DURATION);
    }
}
private final OnCompletionListener beepListener = new OnCompletionListener() {
    public void onCompletion(MediaPlayer mediaPlayer) {
        mediaPlayer.seekTo(0);
    }
};

}
在这个activity中我们扫描了生成的二维码,获取了这个二维码上的信息之后就需要handleDecode方法把扫描到的数据回传到需要的地方,其中我们在调用这个相机的时候库里面也给我们做了相应的处理,只需要直接调用就可以,其中需要注意在activity的几个生命周期方法中去做相应的处理,这里需要结合自己的实际需求。
二:返回数据
刚刚在handleDecode方法中有这个一个方法setResult()这个方法是由activity提供的直接回传当前的数据的方法,配合startActivityForResult一起使用的。
三:解析数据

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
方法中结合自己的需求来对返回的data进行相应的处理。
以上就是怎么样利用ZXing库来实现扫描二维码的实现,谢谢