アンドロイドで1次元バーコードリーダー アプリを作りたい。

てことで、GoogleAPI for Android の Vision.Barcode を使ってみる。リアルタイムでカメラの向きというかバーコードが横を向いてても読み取ってくれる賢い子。MultiProcessor を使うと複数同時に読み取れるけれど、必要性を感じられないので今回はシングルの Processor を使う方向で。

とりあえず、BarcodeScan.java のコード。MainActivity でテストするときは、適宜読み替えを。

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;

import com.google.android.gms.vision.CameraSource;
import com.google.android.gms.vision.Detector;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
import java.io.IOException;

public class BarcodeScan extends AppCompatActivity {
  private static final String TAG = "BarcodeScan";
  private CameraSource cameraSource;
  private SurfaceView surfaceView;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_BarcodeScan);

// バーコードを検出するために Barcode Detector をビルド。
    BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(this)
      .setBarcodeFormats(Barcode.EAN_13).build();

// barcodeDetector に Processor をset し、読み取り結果を Toast
    barcodeDetector.setProcessor(new Detector.Processor() {

// バーコードを受け取った時の処理
    @Override
    public void receiveDetections(final Detector.Detections detections) {
      if (detections.getDetectedItems().size() != 0){
        BarcodeScan.this.runOnUiThread(new Runnable() {
          @Override
          public void run() {
          Toast.makeText(BarcodeScan.this,
            detections.getDetectedItems().valueAt(0).displayValue,
            Toast.LENGTH_LONG).show();
          }
        });
      }
    }
  });

// カメラソースに barcodeDetector をセット。念のためオートフォーカスも設定。
  cameraSource = new CameraSource.Builder(getApplicationContext(), barcodeDetector)
    .setAutoFocusEnabled(true)
    .build();

// プレビューを得るため surfaceView を準備
  surfaceView = (SurfaceView)findViewById(R.id.surfaceView);

// プレビュー用コールバック
  surfaceView.getHolder().addCallback(new SurfaceHolder.Callback(){
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
      try {
        cameraSource.start(surfaceView.getHolder());
      } catch (IOException ioe) {
        Log.e(TAG, "Could not start camera source.", ioe);
      }
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    cameraSource.stop();
    cameraSource.release();
    }
    });
  }
}

layout に SurfaceView を用意。

要件

Google Play service API を利用するので、Android 2.3: Gingerbread 以上のスマホ。パーミッションが面倒なのでターゲットは、 Android 6.0 Marchmallow 以下。

下準備

Android Studio に Google Play sevices SDK をインストール
Tools > Android > SDK Manager
SDK Tools タブで Google Repository をチェック。インストール

AndroidManifest.xml <manifest> タグの間に以下を記載。
<uses-permission android:name="android.permission.CAMERA" />
AndroidManifest.xml の <application>タグの間に下記追加。
<meta-data android:name="com.google.android.gms.vision.DEPENDENCIES"
android:value="barcode" />

アプリモジュールディレクトリの build.gradle ファイルを編集。トップレベルの build.gradle ファイルではないので注意。dependencies に下記追加。-vision を忘れると 65K limit に引っかかる。ウィザードで追加すると、モジュール単位で指定できないので直接編集する。

compile 'com.google.android.gms:play-services-vision:9.0.2'

apply plugin: 'com.android.application'
...なんか色々書いてあると思う
  dependencies {
  compile 'com.google.android.gms:play-services-vision:9.0.2'
}

プロジェクトに反映させるため、Sync Project with Gradle Files をクリック。

Barcode Detector

バーコードを検出するために Barcode Detector をビルド。

BarcodeDetector barcodeDetector = new BarcodeDetector
  .Builder(this)
  .setBarcodeFormats(Barcode.EAN_13)
  .build();

初期設定では、JANコードの様な 1次元バーコード各種、QRコードの様な 2次元バーコードを各種サポートしている。が、読み取り対象を指定してやったほうが動作は軽い。そこでISBN を指定してみる、、読み取ってくれない(泣)。仕方がないので、EAN-13 を指定。13桁の1次元バーコード規格でヨーロッパ仕様だが、まぁJANコードの親戚みたいなものかと。。

QR code も読み取り対象にしたい場合は、パイプで追加。

.setBarcodeFormats(Barcode.EAN_13 | QR_CODE)

参照

vision.barcode リファレンス

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です