Profile Manager Programmer's Guide

EMDK For Android 13.0

Overview

This guide is intended to help the developer configure a device based their application-specific requirements from within the EMDK app. It provides an overview for using Profile Manager to configure Zebra device settings, which includes getting a Profile Manager instance, understanding the contents of the Profile XML, applying a profile, and interpreting results returned by the Profile Manager methods and response XML schema.


Getting Profile Manager

EMDK provides two ways of getting a Profile Manager instance:

  • EMDKManager.getInstanceAsync (recommended)
  • EMDKManager.getInstance

Both are covered below.


EMDKManager.getInstanceAsync

The EMDKManager.getInstanceAsync is an asynchronous call that returns a Profile Manager instance through the registered status listener callback when Profile Manager components such as the MX Management Framework are initialized and ready to use.

Zebra recommends using this method to allow an app to set a profile immediately after a device boots up.


public class MainActivity extends Activity implements EMDKListener, EMDKManager.StatusListener{
//Declare a variable to store ProfileManager object
private ProfileManager profileManager = null;
//Declare a variable to store EMDKManager object
private EMDKManager emdkManager = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  //The EMDKManager object will be created and returned in the callback
  EMDKResults results =
  EMDKManager.getEMDKManager(getApplicationContext(), this);
  //Check the return status of EMDKManager object creation
  if(results.statusCode == EMDKResults.STATUS_CODE.SUCCESS) {
    //EMDKManager object creation success
  }else {
    //EMDKManager object creation failed
  }
}

@Override
protected void onDestroy() {

  super.onDestroy();

  //Clean up the objects created by EMDK manager
  if (profileManager != null)
    profileManager = null;

  if (emdkManager != null) {
    emdkManager.release();
    emdkManager = null;
  }
}
@Override
public void onClosed() {

  //This callback will be issued if the EMDK closes unexpectedly
  if (emdkManager != null) {
    emdkManager.release();
    emdkManager = null;
  }
}

@Override
public void onOpened(EMDKManager emdkManager) {

  this.emdkManager = emdkManager;

  //Get the ProfileManager object using async to process the profiles
  try {
    emdkManager.getInstanceAsync(EMDKManager.FEATURE_TYPE.PROFILE,
          MainActivity.this);
  } catch (EMDKException e) {
    e.printStackTrace();
  }
}

@Override
public void onStatus(EMDKManager.StatusData statusData, EMDKBase emdkBase)
{

  if(statusData.getResult() == EMDKResults.STATUS_CODE.SUCCESS) 
  {
    if(statusData.getFeatureType() == EMDKManager.FEATURE_TYPE.PROFILE)
    {
      profileManager = (ProfileManager)emdkBase;

      if(profileManager != null)               
      {
          // EMDK Profile Manager instance is ready to use
          // Business application logic goes here 
      }
    }
  } else {
    //Error occurred
  }
 }
}

EMDKManager.getInstance

The EMDKManager.getInstance is a synchronous method that immediately returns a Profile Manager instance, independent of the MX Management Framework and other underlying components, and regardless of whether they are initialized and ready to use.

Profile Manager-related components take a few seconds to initialize after the device boots up. If the application tries to access the EMDKManager.getInstance to set the profile immediately, the device boot could result in a permission error because a component is not ready to use.

    
    public class MainActivity extends Activity implements EMDKListener

        //Declare a variable to store ProfileManager object
        private ProfileManager profileManager = null;
        //Declare a variable to store EMDKManager object
        private EMDKManager emdkManager = null;


        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //The EMDKManager object will be created and returned in the callback.
            EMDKResults results = EMDKManager.getEMDKManager(getApplicationContext(),
                    this);
            //Check the return status of EMDKManager object creation.
            if(results.statusCode == EMDKResults.STATUS_CODE.SUCCESS) {
                //EMDKManager object creation success
            }else {
                //EMDKManager object creation failed
            }
        }

        @Override
        protected void onDestroy() {

            super.onDestroy();

            //Clean up the objects created by EMDK manager
            if (profileManager != null)
                profileManager = null;

            if (emdkManager != null) {
                emdkManager.release();
                emdkManager = null;
            }
        }
        @Override
        public void onClosed() {

            //This callback will be issued when the EMDK closes unexpectedly.
            if (emdkManager != null) {
                emdkManager.release();
                emdkManager = null;
            }
        }

        @Override
        public void onOpened(EMDKManager emdkManager) {

            this.emdkManager = emdkManager;

            //Get the ProfileManager object to process the profiles

        profileManager =  (ProfileManager)emdkManager.getInstance(EMDKManager.FEATURE_TYPE.PROFILE);

        }
    }

Profile XML

When the developer creates a profile based on the configuration requirement in the Profile Manager wizard and selects and configures features, the settings are saved in the application's "assets" folder as EMDKConfig.xml.

The sample Profile XML (i.e. EMDKConfig.xml) shown below was generated by the Profile Manager Wizard using MX components such as AppMgr and RemoteScannerMgr:

    
    <?xml version="1.0" encoding="UTF-8"?>
    <!--This is an auto generated document. Changes to this document may cause incorrect behavior.-->
    <wap-provisioningdoc>
    <characteristic type="ProfileInfo">
    <parm name="created\_wizard\_version" value="5.0.1"/>
    </characteristic>
    <characteristic type="Profile">
    <parm name="ProfileName" value="MyProfile"/>
    <parm name="ModifiedDate" value="2016-09-07 14:15:09"/>
    <parm name="TargetSystemVersion" value="6.0"/>
    <characteristic type="AccessMgr" version="4.3">
    <parm name="emdk\_name" value="AccessMgr1"/>
    <parm name="OperationMode" value="2"/>
    <parm name="SystemSettings" value="1"/>
    <parm name="DeletePackagesAction" value="1"/>
    <parm name="DeletePackageNames" value="com.test.error"/>
    <parm name="AddPackagesAction" value="1"/>
    <parm name="AddPackageNames" value="com.symbol.profilesample1"/>
    <parm name="AddPackagesActionAllowXML" value="1"/>
    <parm name="AddPackageNamesAllowXML" value="com.symbol.profilesample1"/>
    <parm name="AllowSubmitXMLAction" value="2"/>
    </characteristic>
    <characteristic type="RemoteScannerMgr" version="5.2">
    <parm name="emdk\_name" value="ResetDefaultScanner"/>
    <parm name="Action" value="3"/>
    <parm name="SerialNumber" value=""/>
    </characteristic>
    <characteristic type="AppMgr" version="5.1">
    <parm name="emdk\_name" value="DemoInstallation"/>
    <parm name="Action" value="Install"/>
    <parm name="APK" value="/sdcard/test.apk"/>
    </characteristic>
    <characteristic type="PowerMgr" version="4.2">
    <parm name="emdk\_name" value="BringToSleep"/>
    <parm name="ResetAction" value="1"/>
    </characteristic>
    <characteristic type="Clock" version="6.0">
    <parm name="emdk\_name" value="SetTime1"/>
    <parm name="AutoTimeZone" value="false"/>
    <parm name="TimeZone" value="GMT-5"/>
    <parm name="AutoTime" value="false"/>
    <parm name="Date" value="2016-09-10"/>
    <parm name="Time" value="12:00:00"/>
    </characteristic>
    </characteristic>
    </wap-provisioningdoc>
  • An EMDKConfig.xml file begins with the node <wap-provisioningdoc> and ends with </wap-provisioningdoc>.

  • After the <wap-provisioningdoc> tag, there is a characteristic node with type named “ProfileInfo” that provides information on the Profile Manager Wizard version used to create the profile. This node is reserved for EMDK internal use only and should NOT be altered. This info is set on the device and is not returned in the response XML.

    
    <characteristic type="ProfileInfo">
    <parm name="created\_wizard\_version" value="5.0.1"/>
    </characteristic>
    
  • Next would be a characteristic node with the type named Profile as shown below. An EMDKConfig.xml file can have one or more Profile nodes based on the number of profiles created.

    
    <characteristic type="Profile">
        <!-- Profile contents -->
    </characteristic>
    
  • Each Profile node contains parm nodes that include ProfileName to identify the profile, ModifiedDate for the profile's last modified date, and TargetSystemVersion for the target MX version chosen to create profile. These parm nodes are reserved for EMDK internal use only and should NOT be manually altered. This info is set on the device and is NOT returned in the response XML.

  • The profile name is used to inform the Profile Manager methods to apply a user-specified profile on the device. The modified date and target MX version are used for profile maintenance such as editing, renaming and modifying profiles in the Profile Manager wizard.

  • Each profile has one or more characteristic feature nodes with parm settings specific to that feature. An example of feature node is shown below.

    
    <characteristic type="AppMgr" version="5.1">
        <parm name="emdk\_name" value=" DemoInstallation"/>
        <parm name="Action" value="Install"/>
        <parm name="APK" value="/sdcard/DemoApp.apk"/>
    </characteristic>
    
  • The characteristic node for each feature will have the attributes type and version.

    • The type indicates the feature

    • The version indicates the feature specification version

  • Each feature characteristic node has one or more parm and characteristic nodes that define the settings for that feature. The parm node (emdk_name) provides the name assigned to that feature, and is used by the Profile Manager API to identify the feature node; it must be a unique name within that profile. The emdk_name value is set on the device and is not returned in the response XML.


Applying Profiles

The ProfileManager API exposes methods such as processProfile and processProfileAsync that are used to apply a XML profile located in the Application’s Assets folder and/or optional profile data passed as extraData to these methods.

The ProfileManager.processProfile is a blocking call that blocks the main thread. To avoid ANRs while applying profile, a developer should call processProfile on a worker thread or use the non blocking call ProfileManager.processProfileAsync, which returns the status through the registered callback. Zebra recommends using the asynchronous method ProfileManager.processProfileAsync rather than the synchronous/blocking method ProfileManager.processProfile.

ProcessProfile and processProfileAsync methods return an EMDKResults object that provides the status of the requested profile action. The code snippet below shows how to use the ProfileManager.processProfileAsync set profile on the device.

    
    public class MyProfileActivity extends Activity implements EMDKListener, ProfileManager.DataListener {

        private EMDKManager emdkManager = null;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            EMDKResults results =
                    EMDKManager.getEMDKManager(getApplicationContext(), this);
            if(results.statusCode == EMDKResults.STATUS_CODE.SUCCESS) {
                //EMDKManager object request success
            }else {
                //EMDKManager object request failed
            }
        }
        @Override
        protected void onDestroy() {
            super.onDestroy();
            //Release EMDKManager on application exit.
            if (emdkManager != null) {
                emdkManager.release();
                emdkManager = null;
            }
        }
        @Override
        public void onOpened(EMDKManager emdkManager) {
            //EMDK issues this callback when the EMDK is ready to use.
            this.emdkManager = emdkManager;

        //Get the ProfileManager object to apply the profiles
        ProfileManager profileManager = (ProfileManager)
                emdkManager.getInstance(EMDKManager.FEATURE_TYPE.PROFILE);

        if(profileManager != null) {
           //Register for callback to receive the processProfileAsync status
           profileManager.addDataListener(MyProfileActivity.this);
           EMDKResults results = profileManager. processProfileAsync("MyProfile1",
                ProfileManager.PROFILE_FLAG.SET,
                (String[])null);
           if(results.statusCode == EMDKResults.STATUS_CODE.PROCESSING) {
               //Applying the profile, status will be returned through
               //the registered callback
           } else {
               //Failed to initiate request to apply the profiles.
           }
        } else {
           //profileManager is null
        }
    }

        @Override
        public void onClosed() {
            //This callback will be issued when the EMDK closes unexpectedly.
            if (emdkManager != null) {
                emdkManager.release();
                emdkManager = null;
            }
        }
        @Override
        public void onData(ProfileManager.ResultData resultData) {
            //processProfileAsync callback method

            EMDKResults result = resultData.getResult();
            if(result.statusCode == EMDKResults.STATUS_CODE.CHECK_XML) {
                String responseXML = result.getStatusString();
                //Parse the responseXML to know the status of profiles applied
            } else if(result.statusCode != EMDKResults.STATUS_CODE.SUCCESS) {
                //Error occurred in applying the profile.
            }
        }
    }

Profile Response

Interpreting EMDKResults

An EMDKResults object provides a status of whether the submitted profile was successfully processed, or if there were errors while processing.

The first step to determine if profile processing was a success or failure would be to inspect the EMDKResults.statusCode field. This field will be of type EMDKResults.STATUS_CODE. When an EMDKResults.statusCode is equal to STATUS_CODE.CHECK_XML, this indicates that you should check the response XML in the EMDKResults.getStatusString() to know the status of the process profile method result. When an EMDKResults.statusCode is not equal to STATUS_CODE.CHECK_XML and also not equal to STATUS_CODE.SUCCESS, this indicates some failure occurred and the detailed error can be obtained from EMDKResults.extendedStatusCode.

In most of the cases, the response Status Code is CHECK_XML regardless of whether the profile was successfully applied.

Refer to the code snippet above within in the onData callback method for determining profile processing result.

Response XML

A response XML of EMDKResults.getStatusString() begins with node <wap-provisioningdoc> and ends with </wap-provisioningdoc>. After the <wap-provisioningdoc> tag, there is a characteristic node with type named “status” that provides information about the status error code, extended status error with the respective description. These error codes are the same errors of EMDKResults.statusCode and EMDKResults.extendedStatusCode. This node can be ignored while parsing the XML if the error from EMDKResults has already been interpreted.

    
    <characteristic type="status">
    <parm name="code" value="6"/>
    <parm name="description" value="Review the XML for details"/>
    <characteristic type="extended\_status">
    <parm name="code" value="0"/>
    <parm name="description" value=""/>
    </characteristic>
    </characteristic>

Each response has one or more characteristic or characteristic-error feature nodes with parm settings specific to that feature. If the feature settings applied successfully, characteristic node is same as input XML with emdk_name parm node removed as shown below.

    
    <characteristic type="AppMgr" version="5.1">
    <parm name="Action" value="Install"/>
    <parm name="APK" value="/sdcard/DemoApp.apk"/>
    </characteristic>

If the feature settings failed to be applied because of an incorrect value, the characteristic node is changed to a characteristic-error node and the parm node that lead to the failure is changed to parm-error node with the description attribute added as shown below.

    
    <characteristic-error type="AppMgr" version="5.1" desc="unsupported">
    <parm-error name="Action" value="Incorrect" desc="unsupported"/>
    <parm name="APK" value="/sdcard/Test.apk"/>
    </characteristic-error>

If the feature settings failed to apply because of other reasons, the characteristic node is changed to a characteristic-error node with the description attribute added as shown below.

Example 1:

    
    <characteristic-error type="RemotePrinterMgr" version="5.2" desc="has not registered with MX Framework yet">
    <parm name="Action" value="3"/>
    </characteristic-error>

Example 2:

    
    <characteristic-error type="RemoteScannerMgr" version="5.2" desc="No connection">
    <parm name="Action" value="3"/>
    <parm name="SerialNumber" value=""/>
    </characteristic-error>

DataCapture profile response is different than other features. If the profile XML submitted contains only the DataCapture profile, the status of the profile setting in EMDKResults.statusCode will have errors such as success, failure and response XML with DataCapture characteristic node to describes the same info. The parm attribute “code” describes the error code and description describes error description in English. This error information is specific to the DataCapture profile only. If any parm values are invalid or unsupported, it automatically picks the default supported value to create DataCapture profile for DataWedge and the errors are not seen normally in the DataCapture profiles.

If the profile submitted is a combination of both DataCapture and Non-DataCapture profile, the EMDKResults.statusCode get the statusCode as CHECK_XML. The application must parse the response to interpret the response XML. The DataCapture response is available under the characteristic node “DataCapture” as shown below.

Example 1: Success Case

    
    <characteristic type="DataCapture">
    <parm name="code" value="0"/>
    <parm name="description" value="Success"/>
    </characteristic>

Example 2: Generic Failure Case

    ::xml
    <characteristic type="DataCapture">
    <parm name="code" value="1"/>
    <parm name="description" value="Failure"/>
    </characteristic>

Sample Response XML Strings

XML - Without Errors

In this example using Profile Manger, a new profile has been created and a RemoteScannerMgr and AppMgr feature has been added. Profile Manager error-checks and provides feedback as values are entered into each parm field. This ensures that the values entered are properly formatted.

XML submitted

    
    <?xml version="1.0" encoding="UTF-8"?><!--This is an auto
    generated document. Changes to this document may cause incorrect
    behavior.--><wap-provisioningdoc>
    <characteristic type="ProfileInfo">
    <parm name="created\_wizard\_version" value="5.0.1"/>
    </characteristic>
    <characteristic type="Profile">
    <parm name="ProfileName" value="MyProfile"/>
    <parm name="ModifiedDate" value="2016-09-08 10:13:05"/>
    <parm name="TargetSystemVersion" value="6.0"/>
    <characteristic type="RemoteScannerMgr" version="5.2">
    <parm name="emdk\_name" value="ResetDefaultScanner"/>
    <parm name="Action" value="3"/>
    <parm name="SerialNumber" value=""/>
    </characteristic>
    <characteristic type="AppMgr" version="5.1">
    <parm name="emdk\_name" value="DemoInstallation"/>
    <parm name="Action" value="Install"/>
    <parm name="APK" value="/sdcard/DemoApp.apk"/>
    </characteristic>
    </characteristic>
    </wap-provisioningdoc>

XML Response - XML String with all settings set successfully.

    
    <?xml version="1.0" encoding="UTF-8"?>
    <wap-provisioningdoc>
        <characteristic type="status">
            <parm name="code" value="6"/>
            <parm name="description" value="Review the XML for details"/>
            <characteristic type="extended\_status">
                <parm name="code" value="0"/>
                <parm name="description" value=""/>
            </characteristic>
        </characteristic>
        <characteristic type="RemoteScannerMgr" version="5.2">
            <parm name="Action" value="3"/>
            <parm name="SerialNumber" value=""/>
        </characteristic >
        <characteristic type="AppMgr" version="5.1">
            <parm name="Action" value="Install"/>
            <parm name="APK" value="/sdcard/DemoApp.apk"/>
        </characteristic>
    </wap-provisioningdoc>

XML with parm-error

In this example, the parm error was returned due to a missing APK, preventing AppMgr from performing the install action.

XML submitted

    
    <?xml version="1.0" encoding="UTF-8"?><!--This is an auto
    generated document. Changes to this document may cause incorrect
    behavior.--><wap-provisioningdoc>
    <characteristic type="ProfileInfo">
    <parm name="created\_wizard\_version" value="5.0.1"/>
    </characteristic>
    <characteristic type="Profile">
    <parm name="ProfileName" value="MyProfile"/>
    <parm name="ModifiedDate" value="2016-09-08 10:13:05"/>
    <parm name="TargetSystemVersion" value="6.0"/>
    <characteristic type="RemoteScannerMgr" version="5.2">
    <parm name="emdk\_name" value="ResetDefaultScanner"/>
    <parm name="Action" value="3"/>
    <parm name="SerialNumber" value=""/>
    </characteristic>
    <characteristic type="AppMgr" version="5.1">
    <parm name="emdk\_name" value="DemoInstallation"/>
    <parm name="Action" value="Install"/>
    <parm name="APK" value="/sdcard/Test.apk"/>
    </characteristic>
    </characteristic>
    </wap-provisioningdoc>

XML Response - XML string with characteristic-error and parm-error because the APK does not exist in the path specified in AppMgr feature.

    
    <?xml version="1.0" encoding="UTF-8"?>
    <wap-provisioningdoc>
    <characteristic type="status">
    <parm name="code" value="6"/>
    <parm name="description" value="Review the XML for details"/>
    <characteristic type="extended\_status">
    <parm name="code" value="0"/>
    <parm name="description" value=""/>
    </characteristic>
    </characteristic>
    <characteristic-error type="RemoteScannerMgr" version="5.2">
    <parm name="Action" value="3"/>
    <parm name="SerialNumber" value=""/>
    </characteristic-error>
    <characteristic-error type="AppMgr" version="5.1" desc="missing">
    <parm-error name="Action" value="Install" desc="apk doesnot exist in
    the path"/>
    <parm name="APK" value="/sdcard/Test.apk"/>
    </characteristic-error>
    </wap-provisioningdoc>

XML with characteristic-error

In this example, the characteristic error was returned because the remote Bluetooth scanner was not connected and was unable to perform the action specified in RemoteScannerMgr.

XML submitted

    
    <?xml version="1.0" encoding="UTF-8"?><!--This is an auto
    generated document. Changes to this document may cause incorrect
    behavior.-->
    <wap-provisioningdoc>
    <characteristic type="ProfileInfo">
    <parm name="created\_wizard\_version" value="5.0.1"/>
    </characteristic>
    <characteristic type="Profile">
    <parm name="ProfileName" value="MyProfile"/>
    <parm name="ModifiedDate" value="2016-09-08 10:13:05"/>
    <parm name="TargetSystemVersion" value="6.0"/>
    <characteristic type="RemoteScannerMgr" version="5.2">
    <parm name="emdk\_name" value="ResetDefaultScanner"/>
    <parm name="Action" value="3"/>
    <parm name="SerialNumber" value=""/>
    </characteristic>
    <characteristic type="AppMgr" version="5.1">
    <parm name="emdk\_name" value="DemoInstallation"/>
    <parm name="Action" value="Install"/>
    <parm name="APK" value="/sdcard/DemoApp.apk"/>
    </characteristic>
    </characteristic>
    </wap-provisioningdoc>

XML Response – XML string with characteristic-error in RemoteScannerMgr because the remote scanner was not connected.

    
    <?xml version="1.0" encoding="UTF-8"?>
    <wap-provisioningdoc>
    <characteristic type="status">
    <parm name="code" value="6"/>
    <parm name="description" value="Review the XML for details"/>
    <characteristic type="extended\_status">
    <parm name="code" value="0"/>
    <parm name="description" value=""/>
    </characteristic>
    </characteristic>
    <characteristic-error type="RemoteScannerMgr" version="5.2" desc="No
    connection">
    <parm name="Action" value="3"/>
    <parm name="SerialNumber" value=""/>
    </characteristic-error>
    <characteristic-error type="AppMgr" version="5.1" desc="missing">
    <parm-error name="Action" value="Install" desc="apk doesnot exist in
    the path"/>
    <parm name="APK" value="/sdcard/DemoApp.apk "/>
    </characteristic-error>
    </wap-provisioningdoc>

XML with characteristic-error and parm-error

In this example, the characteristic error was returned because the remote Bluetooth scanner was not connected and was unable to perform the action specified in the RemoteScannerMgr.

XML submitted - With incorrect or unsupported values

    
    <?xml version="1.0" encoding="UTF-8"?><!--This is an auto
    generated document. Changes to this document may cause incorrect
    behavior.--><wap-provisioningdoc>
    <characteristic type="ProfileInfo">
    <parm name="created\_wizard\_version" value="5.0.1"/>
    </characteristic>
    <characteristic type="Profile">
    <parm name="ProfileName" value="MyProfile"/>
    <parm name="ModifiedDate" value="2016-09-08 10:13:05"/>
    <parm name="TargetSystemVersion" value="6.0"/>
    <characteristic type="RemotePrinterMgr" version="5.2">
    <parm name="emdk\_name" value="ResetDefaultScanner"/>
    <parm name="Action" value="3"/>
    <parm name="SerialNumber" value=""/>
    </characteristic>
    <characteristic type="AppMgr" version="5.1">
    <parm name="emdk\_name" value="DemoInstallation"/>
    <parm name="Action" value="Incorrect"/>
    <parm name="APK" value="/sdcard/Test.apk"/>
    </characteristic>
    </characteristic>
    </wap-provisioningdoc>

XML Response - String with characteristic-error in RemoteScannerMgr because the remote scanner is not connected.

    
    <?xml version="1.0" encoding="UTF-8"?>
    <wap-provisioningdoc>
    <characteristic type="status">
    <parm name="code" value="6"/>
    <parm name="description" value="Review the XML for details"/>
    <characteristic type="extended\_status">
    <parm name="code" value="0"/>
    <parm name="description" value=""/>
    </characteristic>
    </characteristic>
    <characteristic-error type="RemotePrinterMgr" version="5.2" desc="
    has not registered with MX Framework yet">
    <parm name="Action" value="3"/>
    </characteristic-error>
    <characteristic-error type="AppMgr" version="5.1"
    desc="unsupported">
    <parm-error name="Action" value="Incorrect" desc="unsupported"/>
    <parm name="APK" value="/sdcard/Test.apk"/>
    </characteristic-error>
    </wap-provisioningdoc>

Profile XML – DataCapture Feature Only

XML submitted

    
    <?xml version="1.0" encoding="UTF-8"?>
    <!--This is an auto generated document. Changes to this document may
    cause incorrect behavior.-->
    <wap-provisioningdoc>
    <characteristic type="ProfileInfo">
    <parm name="created\_wizard\_version" value="5.0.1"/>
    </characteristic>
    <characteristic type="Profile">
    <parm name="ProfileName" value="MyProfile"/>
    <parm name="ModifiedDate" value="2016-09-19 13:49:42"/>
    <parm name="TargetSystemVersion" value="6.0"/>
    <characteristic type="ActivitySelection" version="0.1">
    <parm name="emdk\_name" value="MyAppSelection1"/>
    <characteristic type="Application">
    <parm name="PrefixAppName" value="false"/>
    <parm name="package" value="com.symbol.test1"/>
    <characteristic type="Activities">
    <parm name="activity" value="\*"/>
    </characteristic>
    </characteristic>
    </characteristic>
    </characteristic>
    </wap-provisioningdoc>

XML Response

If the data capture profile setting succeeds, the EMDKResults.statusCode returns the status code SUCCESS and EMDKResults.getStatusString() gets the response XML string as shown in response XML below.

    
    <?xml version="1.0" encoding="UTF-8"?>
    <wap-provisioningdoc>
    <characteristic type="status">
    <parm name="code" value="0"/>
    <parm name="description" value="Success"/>
    <characteristic type="extended\_status">
    <parm name="code" value="0"/>
    <parm name="description" value=""/>
    </characteristic>
    </characteristic>
    <characteristic type="DataCapture">
    <parm name="code" value="0"/>
    <parm name="description" value="Success"/>
    </characteristic>
    </wap-provisioningdoc>

Profile XML – DataCapture Feature and Non DataCapture

XML submitted

    
    <?xml version="1.0" encoding="UTF-8"?>
    <!--This is an auto generated document. Changes to this document may
    cause incorrect behavior.-->
    <wap-provisioningdoc>
    <characteristic type="ProfileInfo">
    <parm name="created\_wizard\_version" value="5.0.1"/>
    </characteristic>
    <characteristic type="Profile">
    <parm name="ProfileName" value="MyProfile"/>
    <parm name="ModifiedDate" value="2016-09-19 13:59:56"/>
    <parm name="TargetSystemVersion" value="6.0"/>
    <characteristic type="ActivitySelection" version="0.1">
    <parm name="emdk\_name" value="MyAppSelection1"/>
    <characteristic type="Application">
    <parm name="PrefixAppName" value="false"/>
    <parm name="package" value="com.symbol.test1"/>
    <characteristic type="Activities">
    <parm name="activity" value="\*"/>
    </characteristic>
    </characteristic>
    </characteristic>
    <characteristic type="AppMgr" version="5.1">
    <parm name="emdk\_name" value="DemoInstallation"/>
    <parm name="Action" value="Install"/>
    <parm name="APK" value="Test.apk"/>
    </characteristic>
    </characteristic>
    </wap-provisioningdoc>

XML Response

The EMDKResults.statusCode returns the status code CHECK_XML and EMDKResults.getStatusString() gets the response XML string as shown in XML response below.

    
    <?xml version="1.0" encoding="UTF-8"?>
    <wap-provisioningdoc>
    <characteristic type="status">
    <parm name="code" value="6"/>
    <parm name="description" value="Review the XML for details"/>
    <characteristic type="extended\_status">
    <parm name="code" value="0"/>
    <parm name="description" value=""/>
    </characteristic>
    </characteristic>
    <characteristic type="DataCapture">
    <parm name="code" value="0"/>
    <parm name="description" value="Success"/>
    </characteristic>
    <characteristic-error type="AppMgr" version="5.1" desc="missing">
    <parm-error name="Action" value="Install" desc="apk doesnot exist in
    the path"/>
    <parm name="APK" value="Test.apk"/>
    </characteristic-error>
    </wap-provisioningdoc>

Sample Code for Parsing Response XML

Parsing the response XML requires the use of an XML Parser library, which in this example was org.xmlpull.v1.XmlPullParser. This tools allows quick iteration over each START_TAG in the XML response looking for parm and characteristic errors.

Characteristic-Error - A Characteristic-Error is an element that appears in a Result XML document that is used to indicate a failure when processing a corresponding characteristic in a Request XML document.

Parm-Error - A Parm-Error is an element that appears in a Result XML document that is used to indicate a failure when processing a corresponding parm in a Request XML document.

  1. First import the XML parsing library:

    
    import org.xmlpull.v1.XmlPullParser;
    import org.xmlpull.v1.XmlPullParserException;
    
  2. Next get a string representation of the XML Response. Then instantiate a new XMLPullParser object and set its input to the XML Response String object.

    
    String xmlResponse = results.getStatusString();
    XmlPullParser parser = Xml.newPullParser();
    parser.setInput(new StringReader(xmlResponse));
    
  3. Lastly, use XmlPullParser events to iterate over the XML Response nodes searching for parm and characteristic errors. In this simple example, errors are logged for later review. If simple logging is not sufficient, add custom error handling to each of the if blocks inside the START_TAG case.

    
    try {
        int event;
        try {
            event = parser.getEventType();
            while (event != XmlPullParser.END\_DOCUMENT) {
            String name = parser.getName();
            switch (event) {
            case XmlPullParser.START\_TAG:
            if (name.equals("parm-error")) {
            parmName = parser.getAttributeValue(null, "name");
            errorDescription = parser.getAttributeValue(null,
            "desc");
            Log.d(TAG," (Name: " + parmName + ", Error
            Description: " + errorDescription + ")");
            return;
            }
            if (name.equals("characteristic-error")) {
            errorType = parser.getAttributeValue(null, "type");
            errorDescription = parser.getAttributeValue(null,
            "desc");
            Log.d(TAG," (Type: " + errorType + ", Error
            Description: " + errorDescription + ")");
            return;
            }
            break;
            case XmlPullParser.END\_TAG:
            break;
            }
            event = parser.next();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    } catch (XmlPullParserException e) {
    e.printStackTrace();
    }
    } else {
    *//Profile processed sucessfully*
    }
    }
    

Name-Value Pair

ProcessProfile() and processProfileAsync() allow submission of a String Array containing name-value pairs that can be used to replace name-value pairs in a specified profile before installing and activating that profile. The following guide explains the use of name-value pair replacement and a utility method to help create name-value pairs.

String Array (extraData) as Name-Value Pair Array

Method Signature


processProfile(String profileName,
               ProfileManager.PROFILE_FLAG profileFlag,
                String[] extraData);

profileName

The profileName argument can be used to specify the entire profile or a named section of an XML profile.

  • To specify the entire profile, pass the value of the profileName parm as the profileName argument.
  • To specify a section of a profile, build and pass a string containing the top level ProfileName, the featureType of the section, and the emdk_name of the section, all separated by forward slashes:
    • [profileName]/[featureType]/[feature Name]

For example, if a profile is called EmdkSampleProfile-1 and the name given to the Clock feature is clock1, passing profileName as EmdkSampleProfile-1/Clock/clock1 will just process this part of the profile.

featureType

Valid featureTypes:

  • ActivitySelection
  • Barcode
  • MSR
  • Intent
  • Keystroke
  • IP
  • Clock
  • PowerMgr
  • PersistMgr
  • CertMgr
  • AppMgr
  • AccessMgr
  • Wi-Fi
  • GprsMgr

profileFlag

The profileFlag should be ProfileManager.PROFILE_FLAG.SET.

extraData

ExtraData should be an array of Strings. Each string element should be in <Feature_Name>.<Param_name>=<param_value> format (for example bc1.decoder_upce0=true). The Feature_Name can be from multiple features.


Example Usage


//EMDKConfig.xml
<?xml version="1.0" encoding="UTF-8"?><wap-provisioningdoc>
<characteristic type="ProfileInfo">
<parm name="created_wizard_version" value="3.0.2"/>
</characteristic>
<characteristic type="Profile">
<parm name="ProfileName" value="ClockProfile-1"/>
<parm name="ModifiedDate" value="2015-03-16 09:14:43"/>
<characteristic type="Clock" version="4.2">
<parm name="emdk_name" value="Clk01"/>
<parm name="AutoTime" value="false"/>
<parm name="TimeZone" value="GMT+05:30"/>
<parm name="Date" value="2001-01-01"/>
<parm name="Time" value="01:01:01"/>
</characteristic>
<characteristic type="Clock" version="4.2">
<parm name="emdk_name" value="Clk02"/>
<parm name="AutoTime" value="false"/>
<parm name="TimeZone" value="GMT+05:30"/>
<parm name="Date" value="2002-02-02"/>
<parm name="Time" value="02:02:02"/>
</characteristic>
<characteristic type="Clock" version="4.2">
<parm name="emdk_name" value="Clk03"/>
<parm name="AutoTime" value="false"/>
<parm name="TimeZone" value="GMT+05:30"/>
<parm name="Date" value="2003-03-03"/>
<parm name="Time" value="03:03:03"/>
</characteristic>
</characteristic>
</wap-provisioningdoc>


//example.java
String[] extraData = new String[2];
extraData[0]         = "Clk01.Date=2014-10-10"
extraData[1]         = "Clk02.Time=10:10:10"
profileName        = ClockProfile-1/Clock/Clk01
EMDKResults result = mProfileManager.processProfile(
profileName,
ProfileManager.PROFILE_FLAG.SET, extraData);

In example above, the profileName is given as ClockProfile-1/Clock/Clk01. The ClockProfile-1 is the profileName in XML. Clock is the featureType and Clk01 is the featureName. The feature name also referred to as emdk_name.


Name Value Pair Utility Function

CreateNameValuePair

CreateNameValuePair is a static function of the ProfileManager class. This function creates a name-value pair string according to a format that is compatible with the com.symbol.emdk.ProfileManager.processProfile(String, \* PROFILE_FLAG, String[]) function.


/**
 * This function creates a name-value pair string according to the format
 * that is compatible with
 * com.symbol.emdk.ProfileManager.processProfile(String,
 * PROFILE_FLAG, String[]) function.
 * @param emdk_name - emdk name String
 * @param param_name - Parameter name String
 * @param param_value - Parameter value String
 * @return - Name value pair string.
 */
String CreateNameValuePair(String emdk_name, String param_name, String param_value)

//This function returns the String in <emdk_name>.<param_name>=<param_value> format.
//For instance, "clock1.date=2014-10-10";