AndroidでZXingを使ってQRコードを読み取る

ZXing Android Embeddedを使って、QRコードを読み取るアプリを作る方法について。

読み取ったQRコードを方法

設定

build.gradleにライブラリを追加します。

repositories {
    jcenter()
}

dependencies {
    implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
    implementation 'com.android.support:appcompat-v7:25.3.1'   // Minimum 23+ is required
}

android {
    buildToolsVersion '27.0.3' // Older versions may give compile errors
}

AndroidManifest.xmlを編集し、ハードウェアアクセラレーションを有効にします。

<application android:hardwareAccelerated="true" ... >

QRコードを読み取る画面を開く

activity_main.xmlにButtonを追加します。
ボタンを押したらscanBarcode()を実行します。

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/scan_barcode"
    android:onClick="scanBarcode"/>

ボタンが押されたとき、QRコードを読み取るActivityを呼び出します。

public void scanBarcode(View view) {
    new IntentIntegrator(this).initiateScan();
}

オプションを指定することで、QRコード読み込み画面の細かい設定ができます。

public void scanBarcode(View view) {
    new IntentIntegrator(this)
            // 読み取ったときにビープ音を鳴らさない
            .setBeepEnabled(false)
            // 画面の向きを固定しない
            .setOrientationLocked(true)
            // 読み取るバーコードのフォーマットを指定する
            .setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)
            // アクティビティを設定する
            .setCaptureActivity(CustomScannerActivity.class)
            .initiateScan();
}

読み取ったQRコードを受け取る

読み取ったコードを受け取ります。

// Get the results:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
    if(result != null) {
        if(result.getContents() == null) {
            Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
        }
    } else {
        super.onActivityResult(requestCode, resultCode, data);
    }
}

QRコード読み込み画面を自作する

QRコード読み込み画面を自作する方法を解説します。

画面デザイン

プレビューを表示するコンポーネントcom.journeyapps.barcodescanner.DecoratedBarcodeViewを配置します。

例)activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <com.journeyapps.barcodescanner.DecoratedBarcodeView
            android:id="@+id/barcodeView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:zxing_scanner_layout="@layout/custom_barcode_scanner"
    />

</androidx.constraintlayout.widget.ConstraintLayout>

DecoratedBarcodeView内部のデザインをカスタマイズする場合はapp:zxing_scanner_layoutにレイアウトを設定します。

例)custom_barcode_scanner.xml

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <com.journeyapps.barcodescanner.BarcodeView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/zxing_barcode_surface"/>

    <com.journeyapps.barcodescanner.ViewfinderView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/zxing_viewfinder_view"/>

    <TextView android:id="@+id/zxing_status_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center_horizontal"
            android:background="@color/zxing_transparent"
            android:text="このテキストはbarcodeView.setStatusText()で設定できます"
            android:textColor="@color/zxing_status_text"/>
</merge>

ソースコード

DecoratedBarcodeViewを設定します。

読み込むコードの形式を設定します。

val formats = listOf(BarcodeFormat.QR_CODE)
barcodeView.barcodeView.decoderFactory = DefaultDecoderFactory(formats)

その他の設定はbarcodeView.cameraSettingsで設定できます。

    barcodeView.barcodeView.cameraSettings = CameraSettings()

コードを読み込んだときに実行するコールバックを設定します。

barcodeView.decodeContinuous(callback)

コードを読み込んだときの処理を作成します。

val callback = object : BarcodeCallback {
    override fun barcodeResult(result: BarcodeResult?) {
        if (result?.text == null || result.text == lastText) {
            return
        }
        lastText = result.text
        barcodeView.setStatusText(result.text)
    }
    override fun possibleResultPoints(resultPoints: MutableList<ResultPoint>?) {
    }
}

例)MainActivity.kt

class MainActivity : AppCompatActivity() {
    private var lastText: String = ""

    private val callback = object : BarcodeCallback {
        override fun barcodeResult(result: BarcodeResult?) {
            if (result?.text == null || result.text == lastText) {
                return
            }
            lastText = result.text
            barcodeView.setStatusText(result.text)
        }
        override fun possibleResultPoints(resultPoints: MutableList<ResultPoint>?) {
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val formats = listOf(BarcodeFormat.QR_CODE)
        barcodeView.barcodeView.decoderFactory = DefaultDecoderFactory(formats)
        barcodeView.decodeContinuous(callback)
    }

    override fun onResume() {
        super.onResume()
        barcodeView.resume()
    }

    override fun onPause() {
        super.onPause()
        barcodeView.pause()
    }
}

コメントを残す

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

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください