【ライブラリを使おう-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(); } } }; }