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. Theemdk_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.
First import the XML parsing library:
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException;
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));
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 theSTART_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 theprofileName
argument. - To specify a section of a profile, build and pass a string containing the top level
ProfileName
, thefeatureType
of the section, and theemdk_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";