EMDK concurrency guidelines
The EMDKManager instance will always provide only one object (singleton object) of each feature like BarcodeManager, ProfileManager etc. Any attempt to request a new object of the same feature will return the object that is already initiated.
BarcodeManager, SimulScanManager, ProfileManager and Scan&PairManager objects can be created simultaneously but cannot be accessed at the same time.
For example:
- If the BarcodeManager has enabled any one of the barcode device, then no other barcode devices can be enabled at the same time. If camera is used as the barcode device, even the Android Camera APIs cannot be used at that time.
- Also, the SimulScanManager and Scan&PairManager objects cannot enable the respective devices either.
- However, once the BarcodeManager is disabled and released, then the SimulScanManager can enable the SimulScan device.
- An app should either use the DataCapture feature of the ProfileManager or barcode APIs for scanning barcodes but not both
The EMDKManager -> ProfileManager supports simultaneous usage in multiple applications. This means, an individual application needs to not release EMDKManager -> ProfileManager before going to the background. In the previous versions, if an application going to the background did not release the ProfileManager, no other applications could access ProfileManager.
However, the following restrictions will continue to apply:
- Only one instance of EMDKManager can be used in an application.
- Only one instance of ProfileManager can be used in an application.
- Other than the ProfileManager, all other features such as EMDKManager -> BarcodeManager used in an application must be released before another application can use that feature.
- All instances of all features including EMDKManager must be released before the exiting of the application.
Creating a common Application to run on Zebra and Non-Zebra devices
For those who want to write a common application that is capable of running on both Zebra and Non-Zebra devices, care must be taken to use the EMDK components only on the Zebra devices as described below:
The common app containing the EMDK components will not install on a non-Zebra device and will result in the error “Installation error: INSTALL_FAILED_MISSING_SHARED_LIBRARY".
To overcome this problem, the application manifest file must be modified as shown below:
<uses-library android:name="com.symbol.emdk" android:required="false" />
When the common app is launched on a non-Zebra device, the "ClassNotFoundException" exception may occur. To overcome this problem, do not implement the EMDK interfaces in the MainActivity. Instead, create a separate class (ex: EMDKAPIWrapper or any other name) and implement the EMDK related calls in that. When the activity starts, create the EMDKAPIWrapper object during the run time only if you are using the Zebra device.
public class MainActivity extends Activity { private EMDKWrapper emdkWrapper = null; @Override protected void onCreate(Bundle savedInstanceState) { /* Rebranded Zebra devices are set to "Zebra Technologies"*/ /* Motorola devices are set to "Motorola Solutions" */
}if(android.os.Build.MANUFACTURER.contains("Zebra Technologies") || android.os.Build.MANUFACTURER.contains("Motorola Solutions") ){ emdkWrapper = new EMDKWrapper(); } } @Override protected void onDestroy() { //Release the EMDKmanager on Application exit. if (emdkWrapper != null) { emdkWrapper .release(); } } public class EMDKWrapper implements EMDKListener { EMDKManager emdkManager = null; @Override void getEMDKManager(Bundle savedInstanceState) { EMDKResults results = EMDKManager.getEMDKManager(getApplicationContext(), this); if (results.statusCode != EMDKResults.STATUS_CODE.SUCCESS) { //Failed to request the EMDKManager } } } @Override void release() { //Release the EMDKmanager on Application exit. if (emdkManager != null) { emdkManager.release(); emdkManager = null; } } @Override public void onOpened(EMDKManager emdkManager) { this. emdkManager = emdkManager; //The EMDK Manager is ready and now you can call other EMDK APIs. } @Override public void onClosed() { /* EMDKManager is closed abruptly. Call EmdkManager.release() to free the resources used by the current EMDK instance. */ if (emdkManager != null) { emdkManager.release(); emdkManager = null; } }
EMDK Manager opening and closing
The application must call EMDKManager.getEMDKManager to use the EMDK. It is recommended to call this method in the onCreate method to avoid a delay at a later stage. EMDKManager will call the interface EMDKListener.onOpened when the EMDK is ready to use and this callback will be called on main thread only; therefore the application must not block the Main thread to receive EMDKListener.onOpened callback.
The application must call the EMDKManager.release() in the below scenarios:
- On application exit.
- On EMDKListener.onClosed callback.
The EMDKListener.onClosed gets called to notify the application that the EMDKManager object has been abruptly closed due to some failures at EMDK or a lower layer. When this occurs, the application must the release the current EMDK manager instance and get the new EMDK Manager instance
Refer the below code snippets for EMDKManager opening and closing
public class MainActivity extends Activity implements EMDKListener {
private EMDKManager emdkManager = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
EMDKResults results = EMDKManager.getEMDKManager(getApplicationContext(), this);
if (results.statusCode != EMDKResults.STATUS_CODE.SUCCESS) {
//Failed to request the EMDKManager
}
}
}
@Override
protected void onDestroy() {
//Release the EMDKmanager on Application exit.
if (emdkManager != null) {
emdkManager.release();
emdkManager = null;
}
}
@Override
public void onOpened(EMDKManager emdkManager) {
this. emdkManager = emdkManager;
//The EMDK Manager is ready and now you can call other EMDK APIs.
}
@Override
public void onClosed() {
/* EMDKManager is closed abruptly. Call EmdkManager.release() to free the resources used by the current EMDK instance. */
if (emdkManager != null) {
emdkManager.release();
emdkManager = null;
}
}
}
Checking EMDK Version on Device
Zebra Technologies Mobile Devices running the KitKat Android OS will have the EMDK device runtime built-in, but devices running Jelly Bean Android OS will not have the EMDK device runtime built-in. The EMDK version on the device can be checked either by manually or programmatically.
Manual Steps
Goto Settings > Apps > All > EMDK Service. Click on EMDK Service icon to see the version.
Programmatic Steps
Option 1:
Use Android PackageManager to get the EMDK version.
try {
String emdkPkgName = "com.symbol.emdk.emdkservice";
PackageInfo pinfo = getPackageManager().getPackageInfo(emdkPkgName, 0);
String emdkVersion = pinfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
// EMDK does not exists on the device.
}
Option 2:
Use EMDK VersionManager to get the EMDK version as described in the VersionManager API reference.
Selecting EMDK in the MAKE file
The following must be declared in the application MAKE file to use the EMDK SDK library to compile the application:
LOCAL_JAVA_LIBRARIES := com.symbol.emdk
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := libemdk:com.symbol.emdk/com.symbol.emdk.jar
EMDK as a dependency in gradle.build
Use this method to make use of the EMDK in a project with a Compile SDK set above API 19.
In the project folder viewer, open the build.gradle file for the app module.
Add the following to the dependencies section
Windows
dependencies { provided fileTree(include: ['com.symbol.emdk.jar'], dir: 'C:\\Users\\<YOUR USER NAME>\\AppData\\Local\\Android\\sdk\\add-ons\\addon-symbol-emdk_v4.2_API-19\\libs') compile fileTree(exclude: ['com.symbol.emdk.jar'], dir: 'libs')
Mac
dependencies { provided fileTree(include: ['com.symbol.emdk.jar'], dir: '/Users/<YOUR USERNAME/Library/Android/sdk/add-ons/addon-symbol-emdk_v4.2_API-19/libs') compile fileTree(exclude: ['com.symbol.emdk.jar'], dir: 'libs')
Now rebuild your project by selecting Make Project from the Build menu.