はじめに
カメラやGPSなどハードウェア依存の機能を作る時、スマートフォンは便利ですよね。
アプリ版にしかない機能を盛り込む事で、Web版との差別化も出来ます。
今回は、Androidでバーコードスキャナー
機能を実装してみたいと思います。
実行環境
- Android Studio: 4.0.1
- API Level: 29
- Kotlin: 1.3.70
- zxing-android-embedded: 4.1.0
インストール
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
を追加して下さい。
実行
アプリケーションを起動すると、バーコードスキャナーが表示されます。
バーコードをスキャンすると、値がポップアップで表示されます。
その他の設定
ビープ音を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")
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")
CaptureActivity
を継承したアクティビティを作成し、IntentIntegratorの呼び出し時に指定します。
後書き
OCRを勉強中です。
ハードウェア性能も関係しますが、文字の読み取り精度はどの程度なのでしょうか。
とても楽しみです。