LoginSignup
8
9

More than 3 years have passed since last update.

Androidでバーコードスキャナーを実装

Last updated at Posted at 2020-09-30

はじめに

カメラやGPSなどハードウェア依存の機能を作る時、スマートフォンは便利ですよね。
アプリ版にしかない機能を盛り込む事で、Web版との差別化も出来ます。

今回は、Androidでバーコードスキャナー機能を実装してみたいと思います。

実行環境

インストール

diff --git a/app/build.gradle b/app/build.gradle
index be61190..22efbee 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -6,6 +6,11 @@ android {
     compileSdkVersion 29
     buildToolsVersion "29.0.3"

+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
+
     defaultConfig {
         applicationId "com.example.barcodescanner"
         minSdkVersion 24
@@ -29,6 +34,7 @@ dependencies {
     implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
     implementation 'androidx.core:core-ktx:1.3.1'
     implementation 'androidx.appcompat:appcompat:1.2.0'
+    implementation 'com.journeyapps:zxing-android-embedded:4.1.0'
     testImplementation 'junit:junit:4.12'
     androidTestImplementation 'androidx.test.ext:junit:1.1.2'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

基本は、GitHubのREADMEに従ってbuild.gradleに記述し、
gradleを実行すればインストールされます。

メインアクティビティ作成

package com.example.barcodescanner

import android.annotation.SuppressLint
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import com.google.zxing.integration.android.IntentIntegrator
import com.google.zxing.integration.android.IntentResult

class MainActivity : AppCompatActivity()
{
    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)

        val intentIntegrator = IntentIntegrator(this).initiateScan()
    }

    @SuppressLint("ShowToast")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)
    {
        val result: IntentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data)

        if (null != result) {
            val barcodeValue = result.contents

            if (null == barcodeValue) {
                Toast.makeText(this, "Read Error", Toast.LENGTH_LONG).show()
            } else {
                Toast.makeText(this, barcodeValue, Toast.LENGTH_LONG).show()
            }
        } else {
            super.onActivityResult(requestCode, resultCode, data)
        }
    }
}

IntentIntegratorで、処理をバーコードスキャナーに移譲しています。
onActivityResult実装時のお作法として、
呼び出し元が想定されている機能である事を保証する為に、resultCodeの値を突き合わせたりしますが、
Zxingではその辺の処理をparseActivityResult()で行っています。

マニフェストに登録

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 227c879..1e9db0a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.barcodescanner">

@@ -7,6 +8,14 @@
         android:label="@string/app_name"
         android:roundIcon="@mipmap/ic_launcher_round"
         android:supportsRtl="true"
-        android:theme="@style/AppTheme" />
+        android:theme="@style/AppTheme"
+        android:hardwareAccelerated="true">
+        <activity android:name=".MainActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>

 </manifest>

メインアクティビティをマニフェストに登録します。
その際、applicationタグの属性にandroid:hardwareAccelerated=trueを追加して下さい。

実行

Screenshot_20200930-101914.png

アプリケーションを起動すると、バーコードスキャナーが表示されます。

Screenshot_20200930-101930.png

バーコードをスキャンすると、値がポップアップで表示されます。

その他の設定

ビープ音をOFFにする

diff --git a/app/src/main/java/com/example/barcodescanner/MainActivity.kt b/app/src/main/java/com/example/barcodescanner/MainActivity.kt
index 2040542..0fdb9ba 100644
--- a/app/src/main/java/com/example/barcodescanner/MainActivity.kt
+++ b/app/src/main/java/com/example/barcodescanner/MainActivity.kt
@@ -14,7 +14,9 @@ class MainActivity : AppCompatActivity()
     {
         super.onCreate(savedInstanceState)

-        val intentIntegrator = IntentIntegrator(this).initiateScan()
+        val intentIntegrator = IntentIntegrator(this)
+            .setBeepEnabled(false)
+            .initiateScan()
     }

     @SuppressLint("ShowToast")

IntentIntegratorのインスタンス生成時、メソッドチェーンでsetBeepEnabled()を呼び出します。
その際、引数にfalseを渡すとビープ音がOFFになります。

メッセージを設定する

diff --git a/app/src/main/java/com/example/barcodescanner/MainActivity.kt b/app/src/main/java/com/example/barcodescanner/MainActivity.kt
index 2040542..a591c19 100644
--- a/app/src/main/java/com/example/barcodescanner/MainActivity.kt
+++ b/app/src/main/java/com/example/barcodescanner/MainActivity.kt
@@ -14,7 +14,9 @@ class MainActivity : AppCompatActivity()
     {
         super.onCreate(savedInstanceState)

-        val intentIntegrator = IntentIntegrator(this).initiateScan()
+        val intentIntegrator = IntentIntegrator(this)
+            .setPrompt("Test Message")
+            .initiateScan()
     }

     @SuppressLint("ShowToast")

Screenshot_20200930-103940.png

IntentIntegratorのインスタンス生成時、メソッドチェーンでsetPrompt()を呼び出します。
その際、引数に文字列を渡すと画面のメッセージが上書きされます。

画面を横回転させない

package com.example.barcodescanner

import com.journeyapps.barcodescanner.CaptureActivity

class Zxing : CaptureActivity() {}
diff --git a/app/src/main/java/com/example/barcodescanner/MainActivity.kt b/app/src/main/java/com/example/barcodescanner/MainActivity.kt
index 2040542..8155461 100644
--- a/app/src/main/java/com/example/barcodescanner/MainActivity.kt
+++ b/app/src/main/java/com/example/barcodescanner/MainActivity.kt
@@ -14,7 +14,9 @@ class MainActivity : AppCompatActivity()
     {
         super.onCreate(savedInstanceState)

-        val intentIntegrator = IntentIntegrator(this).initiateScan()
+        val intentIntegrator = IntentIntegrator(this).apply {
+            captureActivity = Zxing::class.java
+        }.initiateScan()
     }

     @SuppressLint("ShowToast")

Screenshot_20200930-104625.png

CaptureActivityを継承したアクティビティを作成し、IntentIntegratorの呼び出し時に指定します。

後書き

OCRを勉強中です。
ハードウェア性能も関係しますが、文字の読み取り精度はどの程度なのでしょうか。
とても楽しみです。

8
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
9