android studioで、blluetooth バーコードリーダーを接続して、
hidでバーコード画像を読み取って、その数値を
UI要素の一つである edit textに表示するミニアプリ
を作成したのですが、
バーコードのフォーマットはEAN13ですが、
0424203018608
の画像を読み取ってから
その内容をLog.dで出力すると、
先頭の0が省略されていて、
ですが、その文字列の長さを出力してみると、
12ではなく13になっていました。
スマホ内のそのアプリのedit textも
先頭の0が省略されています。
これはandroid のシステムが
文字列が数値で0で始まっているのなら、
省略した方が読みやすいだろうということで、
処理する、ユーザビリティの一種でしょうか?
私としては、変数に格納する文字列が
0 で始まるときは、そのように格納して欲しいのですが・・・
何か方策はあるのでしょうか?
↓
AndroidでHIDモードのBluetoothバーコードリーダーを使用すると、
スキャンしたバーコードは通常「キーボード入力」として扱われます。
EAN-13のようなバーコードでは、
先頭の `0` が数値と見なされて省略されることがありますが、
実際には見えないゼロ幅スペース(U+200B)や
制御文字が含まれている場合もあります。
### **現象の可能性**
1. **Androidが自動的に数値として扱う**
- `EditText` に入力すると、`int` に変換されて
先頭の `0` が省略される可能性があります。
- `Log.d()` で出力すると、
見た目は `424203018608` でも `length()` を調べると
`13` になっているのは、
制御文字やゼロ幅スペースが含まれている可能性がある。
2. **バーコードリーダーの設定**
- 一部のバーコードスキャナーは、
HIDモードで送信する際に「数値データとして処理する」オプションが
有効になっていることがあります。
### **解決策**
#### **1. `EditText` に正しいフォーマットで表示する**
受け取った文字列を `EditText` にセットする前に、
`String.format()` を使って明示的にゼロ埋めする:
```kotlin
// 余分なスペースや制御文字を除去
val scannedCode = receivedBarcode.trim()
if (scannedCode.length == 12) {
// 13桁にゼロ埋め
val formattedCode = String.format(
"%013d", scannedCode.toLong())
editText.setText(formattedCode)
} else {
editText.setText(scannedCode)
}
```
#### **2. `Log.d()` の前に文字コードを確認する**
バーコードが正しく取得できているかを調べるために、
文字コードをデバッグする:
```kotlin
scannedCode.forEach { c ->
Log.d("DEBUG", "Char: $c Code: ${c.code}")
}
```
もし `0x200B`(ゼロ幅スペース)などの特殊文字が含まれていたら、
それを削除する:
```kotlin
// 制御文字やスペースを削除
val cleanCode = scannedCode.replace(
Regex("[\\p{Cf}\\s]"), "")
```
#### **3. バーコードスキャナーの設定を確認**
バーコードリーダーには、
EAN-13 の「フルフォーマットモード」や「データプレフィックス」
の設定があることが多いです。
設定アプリやマニュアルで、以下の点を確認してください。
- **ゼロ埋め設定**(Zero Padding / Full Data Mode)
- **データ送信フォーマット**(Raw Data / Keyboard Emulation)
- **HIDモードの数値データ変換設定**
#### **4. `InputType` の変更**
`EditText` の `inputType` が `number` になっていると、
Androidが数値として解釈してしまう場合があります。
以下のように `text` に変更することで、
ゼロを省略せずに扱えます。
```xml
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="text" />
```
---
### **まとめ**
Androidは `EditText` の `inputType` や `String` の扱いによって、
先頭の `0` を省略することがあります。
これを防ぐには:
- `String.format("%013d", value.toLong())` でゼロ埋め
- `EditText` の `inputType="text"` に変更
- スキャンデータにゼロ幅スペースなどが含まれていないか `Char.code` を確認
- バーコードリーダーの設定を見直す
この方法で正しく `0424203018608` を扱えるか
試してみてください!
コメント
コメントを投稿