はじめに (対象読者・この記事でわかること)

この記事は、Androidアプリにバーコード読取機能を組み込もうとしているJava/Kotlin開発者を対象としています。
「ZXingを入れるまでもなく、標準ライブラリだけで何が読めるのか?」「JANコード、QRコード、PDF417、DataMatrix…全部使えるの?」といった疑問を解消します。
記事を読み終えると、ML Kit Barcode Scanningがサポートする全13種類のバーコード規格と、それぞれの活用法、権限設定、ProGuard対策、カメラプレビュー最適化のポイントが即座に実装できるようになります。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。 - Android StudioでKotlin/Javaプロジェクトを作成・ビルドできる - CameraXまたはCamera2 APIの基礎知識 - Gradleの依存関係記述(implementation文)の読み書き

Android標準バーコードAPIの変遷と選定理由

2015以前は「ZXing」か「ZBar」の導入が常識でしたが、2019のI/OでGoogleはML Kit Barcode Scanningを発表。2021の「ML Kit v19」で全規格が無料・オフライン・端末内処理となり、標準APIとしての地位を確立しました。
現在ではPlay Services 19.2.0に同梱されており、追加ライブラリを含めてAPKサイズは約200 kB増と、軽量ながら高速・高精度です。特に、QRコードの誤り訂正レベルMまでなら、汚れ・傾き30°まで認識可能です。

サポート済み規格一覧とJava実装コード

ML Kitが認識できるのは以下の13種類です。
1D:CODE-128、CODE-39、CODE-93、CODABAR、EAN-13、EAN-8、UPC-A、UPC-E、ITF
2D:QRコード、PDF417、Aztec、Data Matrix

以下は最小構成で「カメラプレビュー→バーコード取得→Toast表示」までを実装するJavaコードです。
Kotlinへの変換はAndroid Studio「Code → Convert Java File to Kotlin File」で一発です。

ステップ1 Gradle依存関係とAndroidManifest

Groovy
// app/build.gradle implementation 'com.google.mlkit:barcode-scanning:19.2.0' implementation 'androidx.camera:camera-camera2:1.3.0' implementation 'androidx.camera:camera-lifecycle:1.3.0' implementation 'androidx.camera:camera-view:1.3.0'
Xml
<!-- AndroidManifest.xml --> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera.autofocus" />

ステップ2 スキャンオプションとImageAnalysis実装

Java
public class ScanActivity extends AppCompatActivity { private final BarcodeScanner scanner = BarcodeScanning.getClient( new BarcodeScannerOptions.Builder() .setBarcodeFormats( Barcode.FORMAT_QR_CODE, Barcode.FORMAT_EAN_13, Barcode.FORMAT_PDF417) .build()); private void startCamera() { ProcessCameraProvider.getInstance(this).get().bindToLifecycle( this, ContextCompat.getMainExecutor(this), imageAnalysis); } private final ImageAnalysis imageAnalysis = new ImageAnalysis.Builder() .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) .build(); private void analyze(ImageProxy image) { scanner.process(InputImage.fromMediaImage( image.getImage(), image.getImageInfo().getRotationDegrees())) .addOnSuccessListener(barcodes -> { for (Barcode bc : barcodes) { Toast.makeText(this, bc.getDisplayValue() + " (" + bc.getFormat() + ")", Toast.LENGTH_SHORT).show(); } }) .addOnCompleteListener(task -> image.close()); } }

ハマった点:ProGuard/R8で「Detector not found」例外

Play Servicesを用いているため、ProGuardルールを追加し忘れると実行時にcom.google.mlkit.common.MlKitException: Detector not foundが発生します。
原因は、ML KitがJNIでロードする.soが難読化名前で除外されるためです。

解決策:プロガードルール追加

Proguard
-keep class com.google.mlkit.nl.barcode.** { *; } -keep class com.google.mlkit.vision.barcode.** { *; } -keep class com.google.android.gms.vision.** -keepclassmembers class * { @com.google.mlkit.common.annotation.Keep *; }

これでReleaseビルドでも実行時エラーが消え、APKサイズはShrink後も3 MB増しに収まります。

まとめ

本記事では、Android標準のML Kit Barcode Scanningがサポートする13種類のバーコード規格と、Java/Kotlinから最小構成で実装する手順を解説しました。

  • QRコード、JAN(EAN-13)、PDF417、Data Matrixなど主要な規格が無料・オフラインで使える
  • CameraX + ImageAnalysisでリアルタイム読取を30行程度で実装可能
  • ProGuard/R8対策を忘れると実行時にDetectorが見つからないエラーが発生する

この記事を通して、外部ライブラリを増やさずに高速・高精度なバーコード読取機能をアプリに組み込めるようになりました。
次回は、複数のバーコードが重なった画像をImageProxy.YUV_420_888で効率的に処理する方法と、Compose向けのCameraPreviewカスタマイズについて深掘りします。

参考資料