【ライブラリを使おう-ZXing】QRコードを読み取る
今回はAndroidでZXing ライブラリを使ってQRコードを読み取る方法をメモします。
まず、core.jarとjavese.jarをダウンロードします。
本当はGitHubからダウンロードすべきなのですが、jarファイルがなくなっためMavenから取得します。
- javase.jar:http://repo1.maven.org/maven2/com/google/zxing/javase/3.2.1/
- core.jar:http://repo1.maven.org/maven2/com/google/zxing/core/3.2.1/
プロジェクトをビルドしなおすと準備は完了です。
下記のコードは画面をタッチするとオートフォーカスが動き、オートフォーカスが完了するとQRコードを読み込みます。
public class ReaderActivity extends Activity {
private Camera mCamera;
private SurfaceView mSurfaceView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reader);
mSurfaceView = (SurfaceView) findViewById(R.id.preview);
SurfaceHolder holder = mSurfaceView.getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
int cameraId = getCameraId();
mCamera = Camera.open(cameraId);
if (mCamera != null) {
setCameraDisplayOrientation(ReaderActivity.this, cameraId, mCamera);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (mCamera != null) {
mCamera.startPreview();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
});
}
private int getCameraId() {
// 端末に搭載されているカメラの数を取得
int numberOfCameras = Camera.getNumberOfCameras();
int cameraId = 0;
// 各カメラの情報を取得
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo caminfo = new Camera.CameraInfo();
Camera.getCameraInfo(i, caminfo);
// カメラの向きを取得
int facing = caminfo.facing;
if (facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
cameraId = i;
break;
}
}
return cameraId;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mCamera != null && event.getAction() == MotionEvent.ACTION_DOWN) {
mCamera.autoFocus(autoFocusCallback);
}
return super.onTouchEvent(event);
}
public static void setCameraDisplayOrientation(Activity activity, int cameraId, Camera camera) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
private Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
if (!isFinishing() && success) {
camera.setOneShotPreviewCallback(previewCallback);
}
}
};
private PreviewCallback previewCallback = new PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
// 読み込む範囲
int previewWidth = camera.getParameters().getPreviewSize().width;
int previewHeight = camera.getParameters().getPreviewSize().height;
// プレビューデータから BinaryBitmap を生成
PlanarYUVLuminanceSource source =
new PlanarYUVLuminanceSource(data, previewWidth, previewHeight, 0, 0, previewWidth, previewHeight, false);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
// バーコードを読み込む
Reader reader = new MultiFormatReader();
String text = null;
try {
text = reader.decode(bitmap).getText();
} catch (Exception e) {
}
if (text != null) {
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Not Found", Toast.LENGTH_SHORT).show();
}
}
};
}