Secure Storage Manager File Deployment

DataWedge 13.0

Overview

This guide provides instructions on how to securely deploy NG SimulScan templates and DataWedge configuration files (.DB) using Secure Storage Manager (SSM). These files can be deployed either through StageNow or programmatically within your application.

NG SimulScan Template

After generating the NG SimulScan template using Template Builder, securely deploy the template by using one of the following methods:

  • Zebra's StageNow tool
  • Programmatically from your application

Deploy via StageNow

To securely deploy the NG SimulScan template using StageNow:

  1. Launch StageNow on the host computer.

  2. In the StageNow home screen, click Create New Profile from the left menu. image

  3. Select MX version 11.3 or higher (for support of "Deploy a file to an app" option in File Manager). The MX version on the device should match this version selected. See MX documentation for instructions on how to check the version. image

  4. Select Xpert Mode from the list and click Create. image

  5. Enter the profile name. Click Start. image

  6. Scroll down and click the plus (+) sign next to FileMgr. This adds FileMgr to the Config tab on the right side. image

  7. Click Add. image

  8. In the FileMgr settings, enter/select the following:

    • File Action: Deploy file for an application
    • Target Application Field Definition: com.symbol.datawedge/ngsstemplate/TemplateName.xml
      (Replace "TemplateName.xml" with your template XML file name.)

    image

  9. Scroll down and select the following:

    • Source Access Method: File in the Device File System

    image

  10. Click on the ellpsis (...) next to Source Path and File Name. Enter/select the following, then click OK:

    • Media Type on a local Device: Others
    • Enter File Name: /storage/emulated/0/Download/TemplateName.xml
      (Replace "TemplateName.xml" with your template XML file name. Make sure to use the device storage location /storage/emulated/0/Download.)

    image

  11. Click Continue. image

  12. Click Complete Profile. image

  13. The device must be connected to the network during deployment. Use one of the following methods based on the desired tool to deploy the NG SimulScan template to the device:

    • StageNow: Generate the barcode from the StageNow profile. Open StageNow client on the device and scan the barcode.
    • EMM: Export the StageNow XML file from the StageNow installation. Send the XML using either OEMConfig or MX.

Deploy via Application

To securely deploy the NG SimulScan programmatically with your application:

  1. In your AndroidManifest.xml file, add the following permissions:

    <uses-permission android:name="com.zebra.securestoragemanager.securecontentprovider.PERMISSION.WRITE" />
    <uses-permission android:name="com.zebra.securestoragemanager.securecontentprovider.PERMISSION.READ" />
    
  2. In your AndroidManifest.xml file, add the following queries which allows your application to interact with SSM:

    <queries>
        <package android:name="com.zebra.securestoragemanager" />
        <provider android:authorities="com.zebra.securestoragemanager.securecontentprovider"/>
    </queries>
    
  3. In your AndroidManifest.xml file, add the following code to define a FileProvider that allows your application to grant read permissions to files. Replace com.your.package.name with the actual package name of your application.

    <provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="com.your.package.name.provider"
    android:exported="false"
    android:grantUriPermissions="true">
        <meta-data 
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
    </provider>
    
  4. Within your application project, in the "xml" subfolder under the "res" parent folder, add a file named “provider_paths.xml" with the following content:

    <?xml version="1.0" encoding="utf-8"?>
        <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <root-path path="/data/tmp/public" name="public"/>
        <root-path path="/enterprise/usr"  name="user"/>
        <external-path path="." name="external_files"/>
        <files-path path="." name="template"/>
    </paths>
    
  5. Within your application project, create a directory (e.g. documentCaptureTemplates) inside the "assets" folder and copy your XML template within this folder. image

  6. In your application, add a function called uploadTemplates(), which copies files from the "assets" directory and uploads them via the copy function copyFileViaSSM().

    public void uploadTemplates() {
    
    
    AssetManager assetManager = getAssets();
    String[] files = null;
    try {
        files = assetManager.list(ASSET_TEMPLATE_DIR);
    } catch (IOException e) {
        Log.e(TAG, "Failed to get asset file list: " + e.getMessage());
    }
    if (files != null) {
    
        for (String filename : files) {
            InputStream in = null;
            OutputStream out = null;
    
            try {
                in = assetManager.open(ASSET_TEMPLATE_DIR + "/" + filename);
    
                String outDir = getFilesDir().getAbsolutePath() + "/";
    
                File outFile = new File(outDir, filename);
    
                out = new FileOutputStream(outFile);
    
                copyFile(in, out);
                in.close();
                out.flush();
                out.close();
    
                copyFileViaSSM(outFile.getAbsolutePath(), "ngsstemplate");
    
            } 
    
            catch (IOException e) {
                Log.e("tag", "Failed to copy asset file: " + filename, e);
            }
        }
    } 
    
    else {
        Log.d(TAG, "asset file list is null");
    }
    
    } private void copyFile(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[1024];
    int read;
    while ((read = in.read(buffer)) != -1) {
        out.write(buffer, 0, read);
    }
    
    } public void copyFileViaSSM(String sourcePath, String type) {
    File file = new File(sourcePath);
    
    Uri contentUri = FileProvider.getUriForFile(this, this.getPackageName() + ".provider", file);
    
    this.getApplicationContext().grantUriPermission("com.zebra.securestoragemanager", contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); // Needed to grant permission for SSM to read the uri
    
    Uri cpUriQuery = Uri.parse(AUTHORITY_FILE + this.getPackageName());
    
    try {
        ContentValues values = new ContentValues();
        values.put("target_app_package", String.format("{\"pkgs_sigs\": [{\"pkg\":\"%s\",\"sig\":\"%s\"}]}", "com.symbol.datawedge", signature));
        values.put("data_name", String.valueOf(contentUri)); // Passes the content uri as a input source
        values.put("data_type", "3");
        values.put("data_value", "com.symbol.datawedge/" + type + "/" + file.getName()); // Replace “targetPath” with the package name of the target app that is accessing the deployed file (or retrieve the app package using context.getPackageName()) followed by "/" and the full path of the file, e.g. "context.getPackageName()/A.txt"
    
        values.put("data_persist_required", false);
        Uri createdRow = this.getContentResolver().insert(cpUriQuery, values);
        Log.i(TAG, "SSM Insert File: " + createdRow.toString());
    
    } 
    
    catch (Exception e) {
        Log.e(TAG, "SSM Insert File - error: " + e.getMessage() + "\n\n");
    }
    
    }
  7. Call the method uploadTemplates() to upload your template files from your asset folder to DataWedge.

DataWedge Config File

After exporting the DataWedge profile (dwprofile_profilename.db) and/or config file (datawedge.db), securely deploy the file(s) by using one of the following methods:

  • Zebra's StageNow tool
  • Programmatically from your application

Deploy via StageNow

To securely deploy the DataWedge profile or config file using StageNow:

  1. Launch StageNow on the host computer.

  2. In the StageNow home screen, click Create New Profile from the left menu. image

  3. Select MX version 11.3 or higher (for support of "Deploy a file to an app" option in File Manager). The MX version on the device should match this version selected. See MX documentation for instructions on how to check the version. image

  4. Select Xpert Mode from the list and click Create. image

  5. Enter the profile name. Click Start. image

  6. Scroll down and click the plus (+) sign next to FileMgr. This adds FileMgr to the Config tab on the right side. image

  7. Click Add. image

  8. In the FileMgr settings, enter/select the following:

    • File Action: Deploy file for an application
    • Target Application Field Definition: com.symbol.datawedge/config/datawedge.db

      (If deploying the profile, replace "datawedge.db" with the profile file name.)
    • Source Access Method: File in the Device File System

    image

  9. Click on the ellpsis (...) next to Source Path and File Name. Enter/select the following, then click OK:

    • Media Type on a local Device: Others
    • Enter File Name: /storage/emulated/0/Download/datawedge.db
      (If deploying the profile, replace "datawedge.db" with the profile file name. Make sure to use the device storage location /storage/emulated/0/Download.)

    image

  10. Click Continue. image

  11. Click Complete Profile. image

  12. The device must be connected to the network during deployment. Use one of the following methods based on the desired tool to deploy the DataWedge configuration file to the device:

    • StageNow: Generate the barcode from the StageNow profile. Open StageNow client on the device and scan the barcode.
    • EMM: Export the StageNow XML file from the StageNow installation. Send the XML using either OEMConfig or MX.

Deploy via Application

To securely deploy the DataWedge profile or config file with your application:

  1. In your AndroidManifest.xml file, add the following permissions:

    <uses-permission android:name="com.zebra.securestoragemanager.securecontentprovider.PERMISSION.WRITE" />
    <uses-permission android:name="com.zebra.securestoragemanager.securecontentprovider.PERMISSION.READ" />
    
  2. In your AndroidManifest.xml file, add the following queries which allows your application to interact with SSM:

    <queries>
        <package android:name="com.zebra.securestoragemanager" />
        <provider android:authorities="com.zebra.securestoragemanager.securecontentprovider"/>
    </queries>
    
  3. In your AndroidManifest.xml file, add the following code to define a FileProvider that allows your application to grant read permissions to files. Replace "com.your.package.name" with the package name of your application.

    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="com.your.package.name.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>
    
  4. Within your application project, in the "xml" subfolder under the "res" parent folder, add a file named “provider_paths.xml" with the following content:

    <?xml version="1.0" encoding="utf-8"?>
        <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <root-path path="/data/tmp/public" name="public"/>
        <root-path path="/enterprise/usr"  name="user"/>
        <external-path path="." name="external_files"/>
        <files-path path="." name="template"/>
    </paths>
    
  5. Within your application project, create a directory (e.g. ConfigDBs) inside the "assets" folder and copy your DataWedge profile and/or config file within this folder. image

  6. In your application, add a function called uploadTemplates(), which copies files from the "assets" directory and uploads them via the copy function copyFileViaSSM().

    public void uploadConfigDB(boolean isFullDB) {
    
    
    AssetManager assetManager = getAssets();
    String[] files = null;
    
    try {
        files = assetManager.list(ASSET_DB_DIR);
    } 
    catch (IOException e) {
        Log.e(TAG, "Failed to get asset file list: " + e.getMessage());
    }
    
    if (files != null) {
    
        for (String filename : files) {
    
            if (isFullDB &amp;&amp; filename.equals("datawedge.db"))
            {
                integrateFile(assetManager, filename);
            } 
            else if (!isFullDB &amp;&amp; filename.startsWith("dwprofile_"))
            {
                integrateFile(assetManager, filename);
            }
        }
    } 
    else {
        Log.d(TAG, "asset file list is null");
    }
    
    } private void integrateFile(AssetManager assetManager, String filename) { InputStream in = null; OutputStream out = null;
    try {
        in = assetManager.open(ASSET_DB_DIR + "/" + filename);
    
        String outDir = getFilesDir().getAbsolutePath() + "/";
        File outFile = new File(outDir, filename);
    
        out = new FileOutputStream(outFile);
    
        copyFile(in, out);
        in.close();
        out.flush();
        out.close();
    
        copyFileViaSSM(outFile.getAbsolutePath(), "config");
    
    } 
    catch (IOException e) {
        Log.e("tag", "Failed to copy asset file: " + filename, e);
    }
    
    } private void copyFile(InputStream in, OutputStream out) throws IOException { byte[] buffer = new byte[1024]; int read; while ((read = in.read(buffer)) != -1) { out.write(buffer, 0, read); } } public void copyFileViaSSM(String sourcePath, String type) {
    File file = new File(sourcePath);
    
    Uri contentUri = FileProvider.getUriForFile(this, this.getPackageName() + ".provider", file);
    
    this.getApplicationContext().grantUriPermission("com.zebra.securestoragemanager", contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); // Needed to grant permission for SSM to read the uri
    
    Uri cpUriQuery = Uri.parse(AUTHORITY_FILE + this.getPackageName());
    
    try {
        ContentValues values = new ContentValues();
        values.put("target_app_package", String.format("{\"pkgs_sigs\": [{\"pkg\":\"%s\",\"sig\":\"%s\"}]}", "com.symbol.datawedge", signature));
        values.put("data_name", String.valueOf(contentUri)); // Passes the content uri as a input source
        values.put("data_type", "3");
        values.put("data_value", "com.symbol.datawedge/" + type + "/" + file.getName()); // Replace “targetPath” with the package name of the target app that is accessing the deployed file (or retrieve the app package using context.getPackageName()) followed by "/" and the full path of the file, e.g. "context.getPackageName()/A.txt"
    
        values.put("data_persist_required", false);
        Uri createdRow = this.getContentResolver().insert(cpUriQuery, values);
        Log.i(TAG, "SSM Insert File: " + createdRow.toString());
    
    } 
    catch (Exception e) {
        Log.e(TAG, "SSM Insert File - error: " + e.getMessage() + "\n\n");
    }
    
    }
  7. Call the method uploadConfigDB(boolean isFullDB) to upload your configuration DB files from your asset folder to DataWedge.

    • If you are uploading a full configuration DB, pass "true" for the "isFullDB" parameter.
    • If you are uploading a profile DB, pass "false" for the "isFullDB" parameter.

Related Guides: