every Tech Blog

株式会社エブリーのTech Blogです。

Android でのバーコードリーダー実装について

はじめに

この記事は every Tech Blog Advent Calendar 2023 の 16 日目です。
12 月もいよいよ後半となりました。

今回は Android で簡単にバーコードリーダーを実装する方法を紹介したいと思います。

一昔前ですと、バーコードをスキャンするライブラリといえばほぼ ZXing 一強状態でしたが、当初は少しでも暗所に行くと読み取れなくなる、完全に静止しないと読み取れなくなるなどまだまだ精度が低く、システム面ではライトを付ける、オペレーション面ではなるべく静止するなど、創意工夫が必要となっていました。
私自身、先方から何度ももっと読み取り精度を上げてくれと要望を頂いて、何度も苦労しながら改善に改善を加えた苦い記憶があります。

ただ、Google Play services も機能を充実させていき、バージョン 7.8 では Google Mobile Vision という簡単にバーコードをスキャンする機能が提供されるなど、ここ近年ではサードパーティ製のライブラリをわざわざ組み込まなくても簡単にバーコードをスキャンする機能を実装出来る環境が整ってきました。
そして何と今年、UI すら実装が不要という Google Code Scanner API というものまで公開されたため、今回そちらについて情報をまとめてみたいと思います。

Google Code Scanner API とは

https://developers.google.com/ml-kit/vision/barcode-scanning/code-scanner?hl=ja

まず初めに先ほど紹介した Google Mobile Vision についてですが、こちらは既に非推奨となっており、代わりに ML Kit というものが提供されています。
公式では ML Kit の方がよりパフォーマンスや安定性に優れているとの情報が公開されており、Google Code Scanner API はその ML Kit をベースに作られています。

その Google Code Scanner API を使うことでどんなメリットがあるかと言うと、

  • UI を一切実装する必要がない
  • カメラへのアクセス権限のリクエストを実装する必要がない

という、カメラ機能周りを実装する上で一番のハードルとなる部分を全て省いて実装することができます。
具体的な実装方法は次の章から説明していきたいと思います。

実装手順

ここからは実装手順についてまとめていきます。

開発環境

  • Android Studio Giraffe 2022.3.1
  • 開発言語 : Kotlin

リポジトリを追加

ルートの settings.gradle に以下を追加

dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
    }
}

ライブラリの依存関係を追加

app レベルの build.gradle に以下を追加

dependencies {
    implementation("com.google.android.gms:play-services-code-scanner:16.1.0")
}

スキャナモジュールをデバイスに自動的にダウンロードする設定を追加

AndroidManifest.xml に以下を追加

    <application
        ...

        <meta-data
            android:name="com.google.mlkit.vision.DEPENDENCIES"
            android:value="barcode_ui"
            />
    </application>

実装追加

import com.google.mlkit.vision.barcode.common.Barcode
import com.google.mlkit.vision.codescanner.GmsBarcodeScannerOptions
import com.google.mlkit.vision.codescanner.GmsBarcodeScanning
...

class MainActivity : AppCompatActivity() {
    ...

    private fun startReader() {
        val options = GmsBarcodeScannerOptions.Builder()
            .setBarcodeFormats(            // 読み取るバーコードの種別を設定
                Barcode.FORMAT_QR_CODE     // 今回は QR コードを読み取るよう設定
            )
            .enableAutoZoom()              // 自動ズーム有効
            .build()
        val scanner = GmsBarcodeScanning.getClient(this, options)

        // ここを実行するとバーコードスキャンの画面が起動する
        scanner.startScan()
            // 読み取りが成功した時のリスナー
            .addOnSuccessListener { barcode ->
                val rawValue: String? = barcode.rawValue
                Log.d("BarcodeTest", "成功しました : $rawValue")
                rawValue?.let {
                    Toast.makeText(this, rawValue, Toast.LENGTH_SHORT).show()
                }
            }
            // 読み取りキャンセルした時のリスナー
            .addOnCanceledListener {
                Log.d("BarcodeTest", "キャンセルしました")
            }
            // 読み取り失敗した時のリスナー
            .addOnFailureListener { exception ->
                Log.d("BarcodeTest", "失敗しました : ${exception.message}")
            }
    }

上記までで依存関係の設定や実装は完了です。かなり手軽に実装ができました。

実行画面

画面上部にある「コードのスキャン」という文字やバツボタン、画面中央にあるスキャン位置を示す枠などは全て提供された UI が表示されます。
先述した公式サイトのリンクを見ると分かりやすいのですが、バーコードを認識するとスキャン位置を示す枠がバーコードに合わせて移動するアニメーションをするなど、シンプルですが雑な印象にならない UI が組み込まれていました。
また読み取り速度は高速のため、使い勝手の悪さは特に感じませんでした。

読み取り可能なバーコードのフォーマットについて

一般的なバーコードのフォーマットにはほぼ対応しています。対応フォーマットは以下の通りです。

  • Codabar
  • Code 39
  • Code 93
  • Code 128
  • EAN-8
  • EAN-13
  • ITF
  • UPC-A
  • UPC-E
  • Aztec
  • Data Matrix
  • PDF417
  • QR コード

注意点

Google Code Scanner API では UI のカスタマイズが一切できません。UI を自由にカスタマイズしたい場合は ML Kit で実装する必要がありますが、その場合は UI を作成、権限チェックの実装を独自で行う必要があるため、トレードオフで最適な手法を検討する必要があります。
また、バージョン 16.1.0 時点では日本語の QR コードの読み取りに対応しておらず、読み取り時に null になるという仕様になっています。(英数字であれば正常に読み取れます)

おわりに

バーコードリーダーを 1 から実装しようとすると、カメラのチューニング、レイアウトの調整、権限周りの実装など、考慮する点が多く意外と工数がかかるものではありますが、その問題を全て解消できる意味では非常に効果的な手法だと感じました。
唯一レイアウトが調整できないという問題はありますが、バーコードリーダーを実装したいけど実装方法が難しい、レイアウトを組むのが難しい、といった課題がある方は是非 Google Code Scanner API を検討してみてはいかがでしょうか?

少しでもこちらの記事の内容が実装の参考になれば幸いです。