「コンテンツ プロバイダの使用」プログラマ ガイド

DataWedge 11.0

概要

[コンテンツ プロバイダの使用] オプションを使用すると、アプリケーションで DataWedge のコンテンツ プロバイダを利用して、画像 (主に署名読み取りや NextGen SimulScan を使用してスキャンした画像) などの 500KB を超えるファイルからスキャンしたデータを取得できます。コンテンツ プロバイダは、アプリ間で共有できるようにデータをカプセル化する Android アプリ コンポーネントです。

DataWedge のコンテンツ プロバイダは、Android の ContentProvider クラス オブジェクトを通じて一度に 768KB (786,432 バイト) の未加工データしか送信できません。スキャンしたデータがこの制限を超えると、残りのデータは、同じサイズ制限の後続の ContentProvider オブジェクト (URI は最初の ContentProvider に含まれている) で送信されます。URI とは、コンテンツ プロバイダに問い合わせてデータを取得するために使用される文字列のことで、プロバイダとパスが含まれています。ContentProvider を個別の部分に分割するこのプロセスは、未加工のスキャン データが実際のファイル サイズに達するまで繰り返されます。次に、クライアント アプリケーションで、すべての ContentProviders からの未加工データを連結して、最終的な完全な未加工データ オブジェクトを byte[] 形式で再構築する必要があります。

コンテンツ プロバイダ

コンテンツ プロバイダを使用してデータを取得するには、次のセクションの手順に従います。

1.Android マニフェストを変更

次の権限を Android アプリケーションのマニフェストに追加して、そのアプリケーションから DataWedge コンテンツ プロバイダにアクセスできるようにする必要があります。

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

2.コンテンツ プロバイダを有効にする

次のオプションのいずれかを選択して、コンテンツ プロバイダを有効にします。

2a.DataWedge UI を介したコンテンツ プロバイダの有効化

DataWedge UI を介してコンテンツ プロバイダ オプションを有効にするには、DataWedge プロファイルの [インテント出力] セクションに移動し、[インテント出力] を有効にします。

インテント出力

次に、[コンテンツ プロバイダの使用] オプションを有効にします。

コンテンツ プロバイダの使用

2bDataWedge インテント API を介したコンテンツ プロバイダの有効化

DataWedge Intent API を介してコンテンツ プロバイダ オプションを有効にするには、インテント キー intent_use_content_provider を、サポートされている値 true または false とともに使用します。

次のサンプル コードでは、プロファイル Profile009 のコンテンツ プロバイダを有効にする方法を示しています。

    Bundle bMain = new Bundle();
    ArrayList<Bundle> bundlePluginConfig = new ArrayList<>();
    Bundle bConfigIntent = new Bundle();
    Bundle bParamsIntent = new Bundle();
    bParamsIntent.putString("intent_output_enabled", "true");
    bParamsIntent.putString("intent_use_content_provider", "true");
    bConfigIntent.putString("PLUGIN_NAME", "INTENT");
    bConfigIntent.putString("RESET_CONFIG", "true");
    bConfigIntent.putBundle("PARAM_LIST", bParamsIntent);
    bundlePluginConfig.add(bConfigIntent);
    bMain.putParcelableArrayList("PLUGIN_CONFIG", bundlePluginConfig);

    bMain.putString("PROFILE_NAME", "Profile009");
    bMain.putString("PROFILE_ENABLED", "true");
    bMain.putString("CONFIG_MODE", "CREATE_IF_NOT_EXIST");

    Intent iSetConfig = new Intent();
    iSetConfig.setAction("com.symbol.datawedge.api.ACTION");
    iSetConfig.putExtra("com.symbol.datawedge.api.SET_CONFIG", bMain);
    iSetConfig.putExtra("SEND_RESULT", "LAST_RESULT");

    this.sendBroadcast(iSetConfig);

3.コンテンツ プロバイダを使用してインテント出力を処理

コンテンツ プロバイダを使用するように構成されている場合は、最初に、インテント出力プラグインでの構成方法に基づいてスキャン データ インテントが送信されます。

インテント エクストラには、DataWedge コンテンツ プロバイダの URI が含まれています。アプリケーションでは、コンテンツ プロバイダ URI を使用し、ContentResolver によりデータを Cursor オブジェクトに問い合わせる必要があります。

パラメータ

署名の有無ステータス - ドキュメント キャプチャ中に手書きの署名の有無を確認する必要がある場合は、既存のコンテンツ プロバイダ カーソルを通じて署名の有無ステータス パラメータが公開されます。これにより、署名が存在するかどうか、署名の有無ステータスがサポートされているかどうか、または署名の有無ステータスが要求されなかったかどうかが返されます。ドキュメント キャプチャ テンプレートを作成または編集するときは、署名の有無ステータスを要求する必要があります。

カーソル列名 列の値
field_signature_status -2 – 基盤となるスキャナ フレームワークで署名の有無ステータスがサポートされていない
-1 – 署名の有無ステータスが要求されていない
0 – 署名が存在しない
1 – 署名が存在する

サンプル コード

NextGen SimulScan でスキャン データを処理

次のサンプル コードでは、NextGen SimulScan を使用してスキャン データを処理する方法を示します。

    public class MainActivity extends AppCompatActivity {

        public static final String DATA_NEXT_URI = "next_data_uri";
        public static final String FULL_DATA_SIZE = "full_data_size";
        public static final String RAW_DATA_SIZE = "data_buffer_size";
        public static final String DECODE_DATA_EXTRA = "com.symbol.datawedge.decode_data";
        public static final String INTENT_OUTPUT_ACTION = "com.symbol.genericdata.INTENT_OUTPUT";
        public static final String LABEL_TYPE_SIGNATURE = "LABEL-TYPE-SIGNATURE";
        public static final String FIELD_DATA_URI = "com.symbol.datawedge.field_data_uri";
        public static final String DECODED_MODE = "com.symbol.datawedge.decoded_mode";
        public static final String DATA_TAG = "com.symbol.datawedge.data";
        public static final String LABEL_TYPE = "label_type";
        public static final String FIELD_LABEL_TYPE = "field_label_type";
        public static final String DATA_STRING = "field_string_data";
        public static final String DECODE_DATA = "field_raw_data";
        public static final String IMAGE_WIDTH_TAG  =  "field_image_width";
        public static final String IMAGE_HEIGHT_TAG  =  "field_image_height";
        public static final String SINGLE_DECODE_MODE  =  "single_decode";
        public static final String MULTIPLE_DECODE_MODE  =  "multiple_decode";
        public static final String STRING_DATA_KEY  =  "com.symbol.datawedge.data_string";
        public static final String LABEL_TYPE_TAG = "com.symbol.datawedge.label_type";
        public static final String STRING_DATA_KEY_SINGLE_BARCODE  =  "data_string";

        private BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {

            @Override
            public void onReceive(final Context context, final Intent intent) {

                try {
                    String action = intent.getAction();
                    Bundle extras = intent.getExtras();

                    /* ###### Processing scanned data from Intent output [Start] ###### */
                    if (action.equals(INTENT_OUTPUT_ACTION)) {

                        Thread dataProcessingThrad = new Thread(new Runnable() {
                            @Override
                            public void run() {
                                Bundle data = intent.getExtras();
                                if (data != null) {

                                    String decodedMode = data.getString(DECODED_MODE);

                                    /* ###### Processing scanned data when ScanningMode is set as "Single" [Start] ###### */
                                    if (decodedMode.equals(SINGLE_DECODE_MODE)) {
                                        processSingleDecode(data);
                                    }
                                    /* ###### Processing scanned data when ScanningMode is set as "Single" [Finish] ###### */

                                    /* ###### Processing scanned data when ScanningMode is set as "SimulScan" [Start] ###### */
                                    else if (decodedMode.equals(MULTIPLE_DECODE_MODE)) {
                                        processMultipleDecode(data);
                                    }
                                    /* ###### Processing scanned data when ScanningMode is set as "SimulScan" [Finish] ###### */
                                }
                            }
                        });
                        dataProcessingThrad.start();

                    }
                    /* ###### Processing scanned data from Intent output [Finish] ###### */

                } catch (Exception ex) {
                    Toast.makeText(context, ex.getMessage(), Toast.LENGTH_SHORT).show();
                }
            }
        };

        private void processSingleDecode(Bundle data)
        {
            String decodeDataUri = data.getString(DECODE_DATA_EXTRA);
            String barcodeData = "";
            //Check if the data coming through the content provider.
            if(decodeDataUri != null) {
                //Data is coming through the content provider, using a Cursor object to extract data
                Cursor cursor = getContentResolver()
                        .query(Uri.parse(decodeDataUri), null, null, null);
                if (cursor != null) {
                    cursor.moveToFirst();

                    String labelType = cursor
                            .getString(cursor.getColumnIndex(LABEL_TYPE));
                    String dataString = cursor
                            .getString(cursor.getColumnIndex(STRING_DATA_KEY_SINGLE_BARCODE));

                    barcodeData += "\nLabel type: " + labelType;
                    barcodeData += "\nString data: " + dataString;
                }
            }
            else
            {
                //Data is coming through the Intent bundle itself
                String labelType = data.getString(LABEL_TYPE_TAG);
                String dataString = data.getString(STRING_DATA_KEY);

                barcodeData += "\nLabel type: " + labelType;
                barcodeData += "\nString data: " + dataString;
            }

            TextView txtBarcodeData = new TextView(getApplicationContext());
            txtBarcodeData.setText(barcodeData);

            showInUI(txtBarcodeData, null);
            updateStatus("Data processing successful");
        }

        private void processMultipleDecode(Bundle data)
        {
            ArrayList<Bundle> fields = data.getParcelableArrayList(DATA_TAG);
            if(fields == null) //Content provider is not enabled in Intent Output plugin or Scanning mode is not selected as "SimulScan"
            {
                updateStatus("Content provider is not enabled in Intent Output plugin " +
                        "or Scanning mode is not selected as \"SimulScan\".\nPlease check and try again");
                return;
            }

            //Iterate through each field
            for (Bundle field : fields) {

                String decodeDataUri = field.getString(FIELD_DATA_URI);
                Cursor cursor = null;
                if(decodeDataUri != null)
                    cursor = getContentResolver().query(Uri.parse(decodeDataUri),
                            null, null, null);
                if (cursor != null) {
                    int imgWidth = 0;
                    int imgHeight = 0;
                    cursor.moveToFirst();

                    String strResultStatusData = "";

                    String labelType = cursor.
                            getString(cursor.getColumnIndex(FIELD_LABEL_TYPE));

                    strResultStatusData += "\nLabel type: " + labelType;
                    if (labelType.equals(LABEL_TYPE_SIGNATURE)) {
                        strResultStatusData += "\nImage data: ";
                        imgWidth = cursor.getInt(cursor.getColumnIndex(IMAGE_WIDTH_TAG));
                        imgHeight = cursor.getInt(cursor.getColumnIndex(IMAGE_HEIGHT_TAG));
                    } else {
                        String dataString = cursor
                                .getString(cursor.getColumnIndex(DATA_STRING));
                        strResultStatusData += "\nString data: " + dataString;
                    }

                    String nextURI = cursor.getString(cursor.getColumnIndex(DATA_NEXT_URI));
                    byte[] binaryData = null;
                    if (nextURI.isEmpty()) { //No data chunks. All data are available in one chunk
                        binaryData = cursor.getBlob(cursor.getColumnIndex(DECODE_DATA));
                    } else {
                        try {
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                            final String fullDataSize = cursor
                                    .getString(cursor.getColumnIndex(FULL_DATA_SIZE));
                            int bufferSize = cursor.getInt(cursor
                                    .getColumnIndex(RAW_DATA_SIZE));
                            baos.write(cursor.getBlob(cursor
                                    .getColumnIndex(DECODE_DATA))); //Read the first chunk from initial set
                            while (!nextURI.isEmpty()) {
                                Cursor imageDataCursor = getContentResolver()
                                        .query(Uri.parse(nextURI), null,
                                                null, null);
                                if (imageDataCursor != null) {
                                    imageDataCursor.moveToFirst();
                                    bufferSize += imageDataCursor
                                            .getInt(imageDataCursor
                                                    .getColumnIndex(RAW_DATA_SIZE));
                                    byte[] bufferData = imageDataCursor
                                            .getBlob(imageDataCursor
                                                    .getColumnIndex(DECODE_DATA));
                                    baos.write(bufferData);
                                    nextURI = imageDataCursor
                                            .getString(imageDataCursor
                                                    .getColumnIndex(DATA_NEXT_URI));
                                }
                                imageDataCursor.close();

                                updateStatus("Data being processed, please wait..\n" +
                                        bufferSize + "/" + fullDataSize + " bytes merged");
                            }
                            binaryData = baos.toByteArray();
                            baos.close();
                        } catch (final Exception ex) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(MainActivity.this, ex.getMessage(),
                                            Toast.LENGTH_SHORT).show();
                                }
                            });
                        }
                    }

                    final TextView txtBarcodeData = new TextView(getApplicationContext());
                    txtBarcodeData.setText(strResultStatusData);

                    showInUI(txtBarcodeData,null);

                    if (labelType.equals(LABEL_TYPE_SIGNATURE)) {

                        try {
                            //-- Creating YUV Image and Bitmap Image [Start]
                            ByteArrayOutputStream out = new ByteArrayOutputStream();
                            YuvImage yuvImage = new YuvImage(binaryData, ImageFormat.NV21,
                                    imgWidth, imgHeight, null);
                            yuvImage.compressToJpeg(new Rect(0, 0, imgWidth, imgHeight),
                                    50, out);
                            byte[] imageBytes = out.toByteArray();


                            Bitmap bmp = null;
                            if (binaryData != null) {
                                bmp = BitmapFactory.decodeByteArray(imageBytes, 0,
                                        imageBytes.length);
                            }
                            final ImageView img = new ImageView(getApplicationContext());
                            img.setImageBitmap(bmp);
                            showInUI(null,img);
                            //-- Creating YUV Image and Bitmap Image [Finish]
                        }
                        catch (final Exception ex)
                        {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(MainActivity.this,
                                            "Error: " + ex.getMessage(), Toast.LENGTH_SHORT).show();
                                }
                            });
                        }
                    }
                }
            }
            updateStatus("Data processing successful");
        }
        void updateStatus(String status)
        {
            //Show status in UI
        }
        private void showInUI(final TextView textView, final ImageView imageView)
        {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    if(textView != null)
                    //Add text view to UI

                    if(imageView != null)
                        //Add image view to UI
                }
            });
        }
    }

署名読み取りサンプル コード

次のサンプル コードは、署名読み取りを使用してスキャン データを処理する方法を示しています。

    public static final String BARCODE_IMAGE_FORMAT_TAG = "image_format";
    public static final String BARCODE_SIGNATURE_TYPE_TAG = "signature_type";
    public static final String BARCODE_IMAGE_SIZE_TAG = "image_size";
    public static final String BARCODE_IMAGE_DATA_TAG = "com.symbol.datawedge.image_data";
    public static final String SIGNATURE_IMAGE_DATA = "image_data";
    public static final String DATA_NEXT_URI = "next_data_uri";
    public static final String FULL_DATA_SIZE = "full_data_size";
    public static final String RAW_DATA_SIZE = "data_buffer_size";
    public static final String INTENT_OUTPUT_ACTION = "data_buffer_size";


    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(final Context context,final Intent intent) {

            try {
                String action = intent.getAction();
                //Process scanned data from Intent output
                if (action.equals(INTENT_OUTPUT_ACTION)) {

                    Bundle data = intent.getExtras();
                    if (data != null) {

                        String imageDataUri = data.getString(BARCODE_IMAGE_DATA_TAG);
                        if(imageDataUri == null)
                            return;

                        Cursor cursor = getContentResolver().query(Uri.parse(imageDataUri), null, null, null);
                        if (cursor != null) {
                            cursor.moveToFirst();

                            String format = cursor.getString(cursor.getColumnIndex(BARCODE_IMAGE_FORMAT_TAG));
                            String sigType = cursor.getString(cursor.getColumnIndex(BARCODE_SIGNATURE_TYPE_TAG));
                            String size = cursor.getString(cursor.getColumnIndex(BARCODE_IMAGE_SIZE_TAG));

                            String text = "Image format: " + format + "\n";
                            text += "Signature type: " + sigType + "\n";
                            text += "Image size: " + size + "\n";

                            final TextView txt = new TextView(getApplicationContext());
                            txt.setText(text);

                            String nextURI = cursor.getString(cursor.getColumnIndex(DATA_NEXT_URI));
                            byte[] binaryData = null;
                            if (nextURI.isEmpty()) { //No data chunks. All data are available in one chunk
                                binaryData = cursor.getBlob(cursor.getColumnIndex(SIGNATURE_IMAGE_DATA));
                            } else {
                                try {
                                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                                    final String fullDataSize = cursor.getString(cursor.getColumnIndex(FULL_DATA_SIZE));
                                    int bufferSize = cursor.getInt(cursor.getColumnIndex(RAW_DATA_SIZE));
                                    baos.write(cursor.getBlob(cursor.getColumnIndex(SIGNATURE_IMAGE_DATA))); //Read the first chunk from initial set
                                    while (!nextURI.isEmpty()) {
                                        Cursor imageDataCursor = getContentResolver().query(Uri.parse(nextURI), null, null, null);
                                        if (imageDataCursor != null) {
                                            imageDataCursor.moveToFirst();
                                            bufferSize += imageDataCursor.getInt(imageDataCursor.getColumnIndex(RAW_DATA_SIZE));
                                            byte[] bufferData = imageDataCursor.getBlob(imageDataCursor.getColumnIndex(SIGNATURE_IMAGE_DATA));
                                            baos.write(bufferData);
                                            nextURI = imageDataCursor.getString(imageDataCursor.getColumnIndex(DATA_NEXT_URI));
                                        }
                                        imageDataCursor.close();
                                        final int finalBufferSize = bufferSize;
                                        Log.d("TAG","Data being processed, please wait..\n" + finalBufferSize + "/" + fullDataSize + " bytes merged");
                                    }
                                    binaryData = baos.toByteArray();
                                    baos.close();
                                }
                                catch (final Exception ex)
                                {
                                    Toast.makeText(context, ex.getMessage(), Toast.LENGTH_SHORT).show();
                                }
                            }

                            Bitmap bmp = null;
                            if (binaryData != null) {
                                bmp = BitmapFactory.decodeByteArray(binaryData, 0, binaryData.length);
                            }
                            final ImageView img = new ImageView(getApplicationContext());
                            img.setImageBitmap(bmp);
                        }

                        Log.d("TAG","Data processing successful");
                    }
                }

            } catch (Exception ex) {
                Toast.makeText(context, ex.getMessage(), Toast.LENGTH_SHORT).show();
            }
        }
    };

関連ガイド: