「バーコード強調」プログラマ ガイド

DataWedge 13.0

概要

このガイドでは、バーコード強調機能を使用するアプリの作成方法を説明します。[バーコード スキャン] モードから [Barcode Highlighting] モードに切り替える機能が含まれており、バーコード強調機能を使用して、指定された色でさまざまなタイプのバーコードを強調表示する方法を示します。


説明

この例では、バーコード強調機能を使用して、さまざまなフレーバーのアイスクリームのボックスを区別するためのアプリを作成します。各ボックスには 1 つのフレーバーが含まれており、各フレーバーのバーコードは文字列を共有します。ボックスのバーコードがスキャンされると、定義されたルールに基づいて、指定された色で強調表示されます。

  • ストロベリー味のボックスには、テキスト「090986」のバーコードがあります。そのバーコードはピンク色で強調表示されます。
  • チョコレート味のボックスには、テキスト「7777」のバーコードがあります。そのバーコードは茶色で強調表示されます。
  • その他のバーコードは緑色で強調表示されます。

DataWedge の SWITCH_DATACAPTURE API を使用してバーコード スキャンとバーコード強調を切り替え、次のアクションを実行します。

  • [標準] ボタンをタップして、[バーコード スキャン] モードに切り替えます (強調表示なし)。
  • [Highlight] ボタンをタップして、[Barcode Highlighting] モードに切り替えます。

アプリのメイン画面

ソース コードのファイルをダウンロードします。


要件


前提条件

指定されたルールに基づいてバーコード強調をテストするには、以下のようにバーコードを作成します。

  • ストロベリー味のアイスクリームのボックスを表すテキスト「090986」を含むバーコードを作成します。
  • チョコレート味のアイスクリームのボックスを表すテキスト「7777」を含むバーコードを作成します。

バーコードの強調表示

要約すると、このバーコードを強調表示するサンプル アプリを作成する手順は次のとおりです。

  1. UI を作成します
  2. DataWedge プロファイルを作成します
  3. ステータス通知を受信するブロードキャスト レシーバを登録します
  4. [Switch to Barcode Highlighting] モードを追加します
  5. [Switch to Barcode Scanning] モードを追加します

これらの手順の詳細について、次のサブセクションで説明します。

1.UI を作成します

Android アプリケーションを作成します。UI に次の要素を追加します。

  • 標準の [バーコード スキャン] モードに切り替えるボタン ([標準] ボタン)
  • [Barcode Highlighting] モードに切り替えるボタン ([Highlight] ボタン)
  • スキャナのステータスとバーコード強調のステータスを表示する [TextView]
  • スキャンしたデータを表示する [EditText]

アプリのメイン画面

2.DataWedge プロファイルを作成します

DataWedge でプロファイルを作成し、そのプロファイルをアプリに関連付けます。

     

3.ステータス通知を受信するブロードキャスト レシーバを登録します

スキャナ ステータスおよびワークフロー ステータスの通知をリッスンするために、ブロードキャスト受信者を登録します。これには、バーコード強調の通知が含まれます。

public class MainActivity extends AppCompatActivity {

    TextView txtStatus = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        txtStatus = findViewById(R.id.txtStatus);
        registerReceivers();
        registerUnregisterForNotifications(true, "WORKFLOW_STATUS");
        registerUnregisterForNotifications(true, "SCANNER_STATUS");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        registerUnregisterForNotifications(false, "WORKFLOW_STATUS");
        registerUnregisterForNotifications(false, "SCANNER_STATUS");
        unregisterReceivers();
    }

    private void registerReceivers() {
        IntentFilter filter = new IntentFilter();
        filter.addAction("com.symbol.datawedge.api.NOTIFICATION_ACTION");
        filter.addAction("com.symbol.datawedge.api.RESULT_ACTION");
        filter.addCategory(Intent.CATEGORY_DEFAULT);
        registerReceiver(broadcastReceiver, filter);
    }

    private void unregisterReceivers() {

        unregisterReceiver(broadcastReceiver);
    }

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals("com.symbol.datawedge.api.NOTIFICATION_ACTION")) {

                if (intent.hasExtra("com.symbol.datawedge.api.NOTIFICATION")) {
                    Bundle b = intent.getBundleExtra("com.symbol.datawedge.api.NOTIFICATION");
                    String NOTIFICATION_TYPE = b.getString("NOTIFICATION_TYPE");
                    if (NOTIFICATION_TYPE != null) {
                        switch (NOTIFICATION_TYPE) {
                            case "WORKFLOW_STATUS":
                            case "SCANNER_STATUS":

                                String status = b.getString("STATUS");
                                txtStatus.setText("Status: " + status);
                                break;
                        }
                    }
                }
            }
        }
    };

    void registerUnregisterForNotifications(boolean register, String type) {
        Bundle b = new Bundle();
        b.putString("com.symbol.datawedge.api.APPLICATION_NAME", getPackageName());
        b.putString("com.symbol.datawedge.api.NOTIFICATION_TYPE", type);
        Intent i = new Intent();
        i.putExtra("APPLICATION_PACKAGE", getPackageName());
        i.setAction("com.symbol.datawedge.api.ACTION");
        i.setPackage("com.symbol.datawedge");
        if (register)
            i.putExtra("com.symbol.datawedge.api.REGISTER_FOR_NOTIFICATION", b);
        else
            i.putExtra("com.symbol.datawedge.api.UNREGISTER_FOR_NOTIFICATION", b);
        this.sendBroadcast(i);
    }
}

受信したステータスは、UI の一部として [Status TextView] に表示されます。

4.[Switch to Barcode Highlighting] モードを追加します

[Highlight] ボタンのクリック イベントを実装します。コードで、次の手順を実行します:

  • SWITCH_DATACAPTURE API を使用して、バーコード強調を有効にします。
  • 「Rule1」という名前の新しいルールを作成して、テキスト「090986」が含まれているバーコードをピンク色 (#CEF04E6E) で強調表示します。
  • 「Rule2」という名前の新しいルールを作成して、テキスト「7777」が含まれているバーコードを茶色 (#CEF04E6E) で強調表示します。
  • インテントで送信するルール リストに「Rule1」と「Rule2」を追加します。
  • そのルール リストを「barcode_overlay」パラメータに割り当てます。
  • インテントをブロードキャストします。
public void onClickHighlight(View view) { //DataWedge アクションおよび SWITCH_DATACAPTURE API パラメータを指定 Intent i = new Intent(); i.setAction("com.symbol.datawedge.api.ACTION"); i.putExtra("APPLICATION_PACKAGE", getPackageName()); i.setPackage("com.symbol.datawedge"); i.putExtra("SEND_RESULT", "LAST_RESULT"); i.putExtra("com.symbol.datawedge.api.SWITCH_DATACAPTURE", "BARCODE"); Bundle paramList = new Bundle(); //使用するスキャナを指定 (現時点では内蔵のイメージャおよびカメラのみサポート) paramList.putString("scanner_selection_by_identifier", "INTERNAL_IMAGER"); //バーコード強調を有効化  paramList.putString("barcode_highlighting_enabled", "true"); //バーコード強調の「Rule 1」を作成 [開始] Bundle rule1 = new Bundle(); rule1.putString("rule_name", "Rule1"); Bundle rule1Criteria = new Bundle(); //criteria (条件) を設定。contains パラメータを指定します。Bundle bundleContains1 = new Bundle(); bundleContains1.putString("criteria_key", "contains"); bundleContains1.putString("criteria_value", "090986"); //Container は identifier グループの唯一のパラメータ。// 他に ignore case、min length、max length などのパラメータがある ArrayListidentifierParamList = new ArrayList<>(); identifierParamList.add(bundleContains1); //"identifier" グループのパラメータを ParcelableArrayList として criteria リストに追加 rule1Criteria.putParcelableArrayList("identifier", identifierParamList); //Rule バンドルに criteria を追加 rule1.putBundle("criteria", rule1Criteria); //強調表示する色を指定することでアクション バンドルをセットアップ Bundle bundleFillColor = new Bundle(); bundleFillColor.putString("action_key", "fillcolor"); bundleFillColor.putString("action_value", "#CEF04E6E"); ArrayListrule1Actions = new ArrayList<>(); rule1Actions.add(bundleFillColor); rule1.putParcelableArrayList("actions", rule1Actions); //バーコード強調の「Rule 1」を作成 [終了] //バーコード強調の「Rule 2」を作成 [開始] Bundle rule2 = new Bundle(); rule2.putString("rule_name", "Rule2"); Bundle rule2Criteria = new Bundle(); Bundle bundleContains2 = new Bundle(); bundleContains2.putString("criteria_key", "contains"); bundleContains2.putString("criteria_value", "7777"); ArrayListidentifierParamList2 = new ArrayList<>(); identifierParamList2.add(bundleContains2); rule2Criteria.putParcelableArrayList("identifier", identifierParamList2); rule2.putBundle("criteria", rule2Criteria); Bundle rule2BundleStrokeColor = new Bundle(); rule2BundleStrokeColor.putString("action_key", "fillcolor"); rule2BundleStrokeColor.putString("action_value", "#CE7F2714"); ArrayListrule2Actions = new ArrayList<>(); rule2Actions.add(rule2BundleStrokeColor); rule2.putParcelableArrayList("actions", rule2Actions); //バーコード強調の「Rule 1」を作成 [終了] //作成した 2 つのルールをルール リストに追加 ArrayListruleList = new ArrayList<>(); ruleList.add(rule1); ruleList.add(rule2); //そのルール リストを barcode_overlay パラメータに割り当て Bundle ruleBundlebarcodeOverlay = new Bundle(); ruleBundlebarcodeOverlay.putString("rule_param_id", "barcode_overlay"); ruleBundlebarcodeOverlay.putParcelableArrayList("rule_list", ruleList); ArrayListruleParamList = new ArrayList<>(); ruleParamList.add(ruleBundlebarcodeOverlay); paramList.putParcelableArrayList("rules", ruleParamList); i.putExtra("PARAM_LIST", paramList); sendBroadcast(i); }

[Highlight] ボタンをタップして、SESSION_STARTED 状態になってからトリガを押してスキャンします。ステータスは次のように変化します。 PLUGIN_READY > WORKFLOW_READY > WORKFLOW_ENABLED > SESSION_STARTED

セッション開始ステータス

ステータスが SESSION_STARTED に変更されたら、トリガを押してバーコードの強調表示が動作していることを確認します。バーコードは、フレーバーに応じて異なる色で強調表示されます。

  • イチゴ味のアイスクリームのボックスにあるバーコードは、ピンク色で強調表示されます。
  • チョコレート味のアイスクリームのボックスにあるバーコードは、茶色で強調表示されます。
  • スキャンした結果定義されたルールに適合しないバーコードは、緑色で強調表示されます。

バーコードが強調表示される

5.[Switch to Barcode Scanning] モードを追加します

[標準] ボタンのクリック イベントを実装して、[バーコード スキャン] モードに切り替えます (バーコードの強調表示を無効にします)。コードで、次の手順を実行します:

  • SWITCH_DATACAPTURE API を使用して、バーコード強調を無効にします。
public void onClickRegular(View view) { //DataWedge アクションおよび SWITCH_DATACAPTURE API パラメータを指定 Intent i = new Intent(); i.setAction("com.symbol.datawedge.api.ACTION"); i.putExtra("APPLICATION_PACKAGE", getPackageName()); i.setPackage("com.symbol.datawedge"); i.putExtra("SEND_RESULT", "LAST_RESULT"); i.putExtra("com.symbol.datawedge.api.SWITCH_DATACAPTURE", "BARCODE"); Bundle paramList = new Bundle(); //使用するスキャナを指定 (現時点では内蔵のイメージャおよびカメラのみサポート) paramList.putString("scanner_selection_by_identifier", "INTERNAL_IMAGER"); //バーコード強調を無効化 paramList.putString("barcode_highlighting_enabled", "false"); i.putExtra("PARAM_LIST", paramList); sendBroadcast(i); }



インテント出力

バーコード強調オプションを使用したバーコード スキャンのインテント出力では、次の情報が返されます。

フィールド名 説明
string_data デコードされたデータ
長さ デコードされたデータの長さ (文字数)
バーコード タイプ デコードされたデータのシンボル体系のバーコード ID。以下の 「バーコード タイプ表」 を参照してください。
URI 画像データを抽出するためのコンテンツ プロバイダーへの URI。下記の「バーコード強調画像データの抽出」を参照してください。


バーコード タイプ表:

バーコード ID ラベル
1 LABEL-TYPE-CODE39
2 LABEL-TYPE-CODABAR
3 LABEL-TYPE-CODE128
4 LABEL-TYPE-D2OF5
5 LABEL-TYPE-IATA2OF5
6 LABEL-TYPE-I2OF5
7 LABEL-TYPE-CODE93
8 LABEL-TYPE-UPCA
9 LABEL-TYPE-UPCE0
10 LABEL-TYPE-EAN8
11 LABEL-TYPE-EAN13
12 LABEL-TYPE-CODE11
14 LABEL-TYPE-MSI
15 LABEL-TYPE-EAN128
16 LABEL-TYPE-UPCE1
17 LABEL-TYPE-PDF417
19 LABEL-TYPE-CODE39
21 LABEL-TYPE-TRIOPTIC39
22 LABEL-TYPE-BOOKLAND
23 LABEL-TYPE-COUPON
25 LABEL-TYPE-ISBT128
26 LABEL-TYPE-MICROPDF
27 LABEL-TYPE-DATAMATRIX
28 LABEL-TYPE-QRCODE
30 LABEL-TYPE-USPOSTNET
31 LABEL-TYPE-USPLANET
32 LABEL-TYPE-CODE32
33 LABEL-TYPE-ISBT128
34 LABEL-TYPE-JAPPOSTAL
35 LABEL-TYPE-AUSPOSTAL
36 LABEL-TYPE-DUTCHPOSTAL
37 LABEL-TYPE-MAXICODE
38 LABEL-TYPE-CANPOSTAL
39 LABEL-TYPE-UKPOSTAL
44 LABEL-TYPE-MICROQR
45 LABEL-TYPE-AZTEC
48 LABEL-TYPE-GS1-DATABAR
49 LLABEL-TYPE-GS1-DATABAR-LIM
50 LABEL-TYPE-GS1-DATABAR-EXP
52 LABEL-TYPE-US4STATE
53 LABEL-TYPE-US4STATE-FICS
55 LABEL-TYPE-WEBCODE
57 LABEL-TYPE-MATRIX-2OF5
72 LABEL-TYPE-UPCA
73 LABEL-TYPE-UPCE0
74 LABEL-TYPE-EAN8
75 LABEL-TYPE-EAN13
80 LABEL-TYPE-UPCE1
81 LABEL-TYPE-COMPOSITE-AB
82 LABEL-TYPE-COMPOSITE-AB
83 LABEL-TYPE-COMPOSITE-AB
84 LABEL-TYPE-COMPOSITE-AB
85 LABEL-TYPE-COMPOSITE-AB
86 LABEL-TYPE-COMPOSITE-AB
87 LABEL-TYPE-COMPOSITE-AB
88 LABEL-TYPE-COMPOSITE-AB
89 LABEL-TYPE-COMPOSITE-C
90 LABEL-TYPE-TLC39
97 LABEL-TYPE-COMPOSITE-AB
98 LABEL-TYPE-COMPOSITE-AB
99 LABEL-TYPE-COMPOSITE-AB
100 LABEL-TYPE-COMPOSITE-AB
101 LABEL-TYPE-COMPOSITE-AB
102 LABEL-TYPE-COMPOSITE-AB
103 LABEL-TYPE-COMPOSITE-AB
104 LABEL-TYPE-COMPOSITE-AB
105 LABEL-TYPE-SIGNATURE
114 LABEL-TYPE-CHINESE-2OF5
115 LABEL-TYPE-KOREAN-3OF5
136 LABEL-TYPE-UPCA
137 LABEL-TYPE-UPCE0
138 LABEL-TYPE-EAN8
139 LABEL-TYPE-EAN13
144 LABEL-TYPE-UPCE1
161 LABEL-TYPE-OCR
180 LABEL-TYPE-DATABAR-COUPON
183 LABEL-TYPE-HANXIN
193 LABEL-TYPE-GS1-DATAMATRIX
194 LABEL-TYPE-GS1-QRCODE
195 LABEL-TYPE-MAILMARK
196 LABEL-TYPE-DOTCODE
198 MULTICODE-DATA-FORMAT
200 LABEL-TYPE-GRIDMATRIX
205 LABEL-TYPE-FINNISHPOSTAL-4S
255 LABEL-TYPE-UNDEFINED

バーコード強調画像データを抽出する

DataWedge コンテンツ プロバイダにアクセスするために、アプリケーション マニフェスト ファイルに次の権限が追加されていることを確認します。

<uses-permission android:name="com.symbol.datawedge.permission.contentprovider" />

重要: DataWedge アプリでは、Android 11 (API 30) によるパッケージ可視性の制限により、AndroidManifest.xml ファイルに次の <queries> 要素を含める必要があります。

    <queries>
        <package android:name="com.symbol.datawedge" />
    </queries>

[URI] フィールドの値を使用して、DataWedge コンテンツ プロバイダにアクセスする URI を取得します。次に、ContentResolver を使用して URI を渡し、Cursor オブジェクトを取得します。Cursor オブジェクトには、次の 2 つの列があります。

名前 説明
raw_data 画像データを byte[] 形式で格納します
next_data_uri 残りの画像データの取得に使用する URI。残りの画像データがない場合、このフィールドは空になります。

raw_data を読み取りそれを ByteArrayOutputStream オブジェクトに保存します。next_data_uri が空でない場合は、next_data_uri 列に指定されている URI から raw_data を読み取ります。next_data_uri が空になるまで、引き続き raw_data フィールドを読み取って値を ByteArrayOutputStream オブジェクトに格納します。これは、次のように while ループを使用して実行できます。

String uri = jsonObject.getString("uri");
Cursor cursor = getContentResolver().query(Uri.parse(uri),null,null,null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if(cursor != null)
{
    cursor.moveToFirst();
    baos.write(cursor.getBlob(cursor.getColumnIndex("raw_data")));
    String nextURI = cursor.getString(cursor.getColumnIndex("next_data_uri"));
    while (nextURI != null && !nextURI.isEmpty())
    {
        Cursor cursorNextData = getContentResolver().query(Uri.parse(nextURI),
                null,null,null);
        if(cursorNextData != null)
        {
            cursorNextData.moveToFirst();
            baos.write(cursorNextData.getBlob(cursorNextData.
                    getColumnIndex("raw_data")));
            nextURI = cursorNextData.getString(cursorNextData.
                    getColumnIndex("next_data_uri"));

            cursorNextData.close();
        }

    }
    cursor.close();
}

すべての値が画像データ用に保存されている場合は、下の表に示す画像出力でサポートされているフィールド名 (例えば「width」、「height」など) によってマップされた値を読み取り、Bitmap オブジェクトを構築します。

画像出力

フィールド名 タイプ 説明
width int 画像の幅 (ピクセル単位)
height int 画像の高さ (ピクセル単位)
size int 画像バッファのサイズ (ピクセル単位)
stride int 画像の 1 行の幅 (ピクセル単位)
imageformat string サポートされている形式: Y8、YUV
注: YUV 形式は NV12 形式として解釈する必要があります。
orientation int 画像バッファの回転角度 (度単位)。値: 0、90、180、270


ImageProcessing クラスの getBitmap() メソッド (下に示す) を使用して、Bitmap オブジェクトを取得します。

int width = 0;
int height = 0;
int stride = 0;
int orientation = 0;
String imageFormat = "";

width = jsonObject.getInt("width");
height = jsonObject.getInt("height");
stride = jsonObject.getInt("stride");
orientation = jsonObject.getInt("orientation");
imageFormat = jsonObject.getString("imageformat");

Bitmap bitmap = ImageProcessing.getInstance().getBitmap(baos.toByteArray(),imageFormat, orientation,stride,width, height);

Class ImageProcessing:

/*
* Copyright (C) 2018-2021 Zebra Technologies Corp
* All rights reserved.
*/
package com.zebra.idscanningapp;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;

import java.io.ByteArrayOutputStream;

public class ImageProcessing{

    private final String IMG_FORMAT_YUV = "YUV";
    private final String IMG_FORMAT_Y8 = "Y8";

    private static ImageProcessing instance = null;

    public static ImageProcessing getInstance() {

        if (instance == null) {
            instance = new ImageProcessing();
        }
        return instance;
    }

    private ImageProcessing() {
        //Private Constructor
    }

    public Bitmap getBitmap(byte[] data, String imageFormat, int orientation, int stride, int width, int height)
    {
        if(imageFormat.equalsIgnoreCase(IMG_FORMAT_YUV))
        {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int uvStride = ((stride + 1)/2)*2;  // calculate UV channel stride to support odd strides
            YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21, width, height, new int[]{stride, uvStride});
            yuvImage.compressToJpeg(new Rect(0, 0, stride, height), 100, out);
            yuvImage.getYuvData();
            byte[] imageBytes = out.toByteArray();
            if(orientation != 0)
            {
                Matrix matrix = new Matrix();
                matrix.postRotate(orientation);
                Bitmap bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
                return Bitmap.createBitmap(bitmap, 0 , 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
            }
            else
            {
                return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
            }
        }
        else if(imageFormat.equalsIgnoreCase(IMG_FORMAT_Y8))
        {
            return convertYtoJPG_CPU(data, orientation, stride, height);
        }

        return null;
    }


    private Bitmap convertYtoJPG_CPU(byte[] data, int orientation, int stride, int height)
    {
        int mLength = data.length;
        int [] pixels = new int[mLength];
        for(int i = 0; i < mLength; i++)
        {
            int p = data[i] & 0xFF;
            pixels[i] = 0xff000000 | p << 16 | p << 8 | p;
        }
        if(orientation != 0)
        {
            Matrix matrix = new Matrix();
            matrix.postRotate(orientation);
            Bitmap bitmap = Bitmap.createBitmap(pixels, stride, height, Bitmap.Config.ARGB_8888);
            return Bitmap.createBitmap(bitmap, 0 , 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        }
        else
        {
            return Bitmap.createBitmap(pixels, stride, height, Bitmap.Config.ARGB_8888);
        }
    }
}



関連ガイド: