最近はこの類を"スマートターミナル"と呼ぶのでしょうか?
Panasonic製の頑丈端末TOUGHPAD(FZ-N1/FZ-X1)のバーコードリーダを制御してみた記録を残したいと思います。
TOUGHPAD SDK内にサンプルコードはあるのですが、 Fragment
で書かれているので Activity
に落としてみました。
Qiitaに書こうか迷いましたが、限りなく需要がなさそうなのでここに書くことにしました。
製品レビューっぽいことは行いません。
詳細はPanasonicの公式ページを参照ください。
panasonic.biz
panasonic.biz
必要なもの
- PC
- TOUGHPAD本体(FZ-N1/FZ-X1)
実装手順
手順は省略。
TOUGHPADライブラリ読み込み
TOUGHPAD SDKをダウンロードし、 Toughpad.jar
をプロジェクトの libs
(無ければ掘る)にコピー。
.exe
で落ちてくるので、MacやLinuxをお使いの際はなんとかしてWindowsで展開してください…。
app
モジュールの方の build.gradle
に下記記載があることを確認。無ければ追記。
(AndroidStudioのバージョンによっては自動記述されない時期があったため。)
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
...
バーコード読み取りClass(Activity)を作成
TOUGHPAD SDK同梱のサンプルコードをそのまま Activity
に落としたものです。
package com.example.zebra.toughpadsimplebarcodereaderdemo;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.concurrent.TimeoutException;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.panasonic.toughpad.android.api.ToughpadApi;
import com.panasonic.toughpad.android.api.ToughpadApiListener;
import com.panasonic.toughpad.android.api.barcode.BarcodeData;
import com.panasonic.toughpad.android.api.barcode.BarcodeException;
import com.panasonic.toughpad.android.api.barcode.BarcodeListener;
import com.panasonic.toughpad.android.api.barcode.BarcodeReader;
import com.panasonic.toughpad.android.api.barcode.BarcodeReaderManager;
BarcodeReadableActivity.
{@code onRead(...)}
public abstract class BarcodeReadableActivity extends AppCompatActivity
implements ToughpadApiListener, BarcodeListener {
EnableReaderTask enableReaderTask;
private List<BarcodeReader> readers;
private BarcodeReader selectedReader;
@Override
protected void onResume() {
super.onResume();
enableReaderTask = new EnableReaderTask(new WeakReference<>(this));
initializeBarcodeReader();
}
@Override
protected void onPause() {
super.onPause();
if (enableReaderTask.getStatus() == AsyncTask.Status.RUNNING
|| enableReaderTask.getStatus() == AsyncTask.Status.PENDING) {
enableReaderTask.cancel(true);
} else if (enableReaderTask.getStatus() == AsyncTask.Status.FINISHED) {
switchSoftwareTrigger(false);
}
ToughpadApi.destroy();
}
public void initializeBarcodeReader() {
if (ToughpadApi.isAlreadyInitialized()) {
return;
}
readers = null;
selectedReader = null;
try {
ToughpadApi.initialize(this, this);
} catch (RuntimeException ex) {
if (BuildConfig.DEBUG) {
printDebugLog(ex.getMessage());
}
}
}
@Override
public void onApiConnected(int version) {
readers = BarcodeReaderManager.getBarcodeReaders();
XXX
if (readers == null || readers.size() == 0) {
return;
}
selectedReader = readers.get(0);
enableReaderTask.execute(selectedReader);
}
@Override
public void onApiDisconnected() {
releaseBarcodeReader();
}
Callback when barcode is scanned.
@param bsObj
@param result
@Override
public final void onRead(BarcodeReader bsObj, final BarcodeData result) {
if (BuildConfig.DEBUG) {
printDebugLog(
String.format(getString(R.string.read_barcode_logging_format),
bsObj.getDeviceName(), result.getSymbology()));
printDebugLog(
String.format(getString(R.string.read_barcode_text_logging_format), result.getTextData()));
}
runOnUiThread(new Runnable() {
public void run() {
BarcodeReadableActivity.this.onRead(result);
}
});
}
Overridable callback when barcode is scanned.
@param barcodeData
public void onRead(BarcodeData barcodeData) {
}
Fire a software-trigger.
public void switchSoftwareTrigger(boolean status) {
try {
selectedReader.pressSoftwareTrigger(status);
} catch (IllegalStateException | BarcodeException ex) {
printDebugLog(ex.getMessage());
}
}
public void toggleHardwareTrigger(boolean status) {
try {
selectedReader.setHardwareTriggerEnabled(status);
} catch (BarcodeException | IllegalStateException ex) {
printDebugLog(ex.getMessage());
}
}
private void releaseBarcodeReader() {
try {
selectedReader.disable();
selectedReader.clearBarcodeListener();
printDebugLog(String.format(
getString(R.string.barcode_reader_available_device_name),
selectedReader.getDeviceName()));
} catch (BarcodeException ex) {
printDebugLog(ex.getMessage());
}
}
public void printDebugLog(String text) {
if (BuildConfig.DEBUG) {
Log.d(this.getClass().getSimpleName(), text);
}
}
private static class EnableReaderTask extends AsyncTask<BarcodeReader, Void, Boolean> {
private WeakReference<BarcodeReadableActivity> activityWeakReference;
private ProgressDialog dialog;
EnableReaderTask(WeakReference<BarcodeReadableActivity> activityWeakReference) {
this.activityWeakReference = activityWeakReference;
}
private boolean isActivityExist() {
return this.activityWeakReference.get() != null;
}
@Override
protected void onPreExecute() {
if (!isActivityExist()) {
return;
}
if (dialog == null) {
dialog = new ProgressDialog(activityWeakReference.get());
dialog.setCancelable(false);
dialog.setIndeterminate(true);
dialog.setMessage(
activityWeakReference.get().getString(R.string.title_barcode_reader_connecting));
}
dialog.show();
}
@Override
protected Boolean doInBackground(BarcodeReader... params) {
if (!isActivityExist()) {
return false;
}
try {
params[0].enable(3000);
params[0].addBarcodeListener(activityWeakReference.get());
return true;
} catch (BarcodeException | TimeoutException ex) {
activityWeakReference.get().printDebugLog(ex.getMessage());
return false;
}
}
@Override
protected void onPostExecute(Boolean result) {
if (!isActivityExist()) {
return;
}
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
if (result) {
activityWeakReference.get().printDebugLog(
String.format(activityWeakReference.get().getString(
R.string.barcode_reader_available_device_name),
activityWeakReference.get().selectedReader.getDeviceName()));
activityWeakReference.get().toggleHardwareTrigger(true);
}
}
@Override
protected void onCancelled() {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
}
}
}
ダラダラと書いてありますが要約すると、
バーコードを読み取りたい画面( Activity
)で BarcodeReadableActivity
を継承すると、
onRead(BarcodeData barcodeData) {...}
コールバックで読み取り値を受け取れるようになります。
ということです。
読み取り結果を受け取ってみる
レイアウト
xml version="1.0" encoding="utf-8"
<androidsupportconstraintConstraintLayout
xmlnsandroid="http://schemas.android.com/apk/res/android"
xmlnsapp="http://schemas.android.com/apk/res-auto"
xmlnstools="http://schemas.android.com/tools"
androidlayout_width="match_parent"
androidlayout_height="match_parent"
applayout_behavior="@string/appbar_scrolling_view_behavior"
toolscontext="com.example.zebra.toughpadsimplebarcodereaderdemo.MainActivity"
toolsshowIn="@layout/activity_main">
<ScrollView
androidlayout_width="368dp"
androidlayout_height="231dp"
androidlayout_marginBottom="8dp"
androidlayout_marginTop="8dp"
applayout_constraintBottom_toBottomOf="parent"
applayout_constraintTop_toTopOf="parent"
applayout_constraintVertical_bias="0.03"
toolslayout_editor_absoluteX="8dp">
<LinearLayout
androidlayout_width="match_parent"
androidlayout_height="wrap_content"
androidorientation="vertical">
<TextView
androidid="@+id/text_view"
androidlayout_width="match_parent"
androidlayout_height="wrap_content"
androidtext="@string/hint_text"
applayout_constraintBottom_toBottomOf="parent"
applayout_constraintLeft_toLeftOf="parent"
applayout_constraintRight_toRightOf="parent"
applayout_constraintTop_toTopOf="parent"
applayout_constraintVertical_bias="0.223"/>
</LinearLayout>
</ScrollView>
</androidsupportconstraintConstraintLayout>
コード
package com.example.zebra.toughpadsimplebarcodereaderdemo;
import android.os.Bundle;
import android.widget.TextView;
import com.panasonic.toughpad.android.api.barcode.BarcodeData;
public class MainActivity extends BarcodeReadableActivity {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.text_view);
}
@Override
public void onRead(BarcodeData barcodeData) {
appendResult(barcodeData.getTextData());
}
private void appendResult(final String result) {
if (getText(R.string.hint_text).equals(textView.getText().toString())) {
textView.setText("");
}
textView.append("\n" + result);
}
}
以上の実装で、簡単に読み取り値を受け取れます。
かなり雑ですが、こんな感じです。
サンプルコードを GitHubにあげています。
以上です。