Overview
EMDK for Android 7.1 (and higher) supports Android multi-user mode, which allows a device to have Primary and Secondary users, each with its own sets of apps, capabilities and access privileges. When running an EMDK app on a device with multiple users, EMDK is enabled only for the active user. Apps must be designed to release internal device resources and the EMDKManager whenever the app goes to the background (which triggers a "user switch") and to reacquire the resources when the app returns to the foreground. This is done by listening with intents:
ACTION_USER_BACKGROUND
- release internal resources when heardACTION_USER_FOREGROUND
- reacquire resources when heard
The EMDK service automatically releases external component resources (i.e. scanner, serial and SimulScan objects) when an app goes to the background to make them available to the foreground app. Scanning resources must be programmatically reacquired when the EMDK app returns to the foreground.
Example
The code below demonstrates how an app should release and reacquire EMDK resources when switching users on a device.
public class MainActivity extends Activity implements EMDKListener, DataListener, StatusListener, ScannerConnectionListener {
private EMDKManager emdkManager = null;
private BarcodeManager barcodeManager = null;
private Scanner scanner = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_BACKGROUND);
filter.addAction(Intent.ACTION_USER_FOREGROUND);
registerReceiver(broadcastReceiver, filter);
} catch (Exception ex) {
ex.printStackTrace();
}
EMDKResults results = EMDKManager.getEMDKManager(getApplicationContext(), this);
if (results.statusCode != EMDKResults.STATUS_CODE.SUCCESS) {
return;
}
}
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
boolean appSentToBackground = intent.getAction().equals(Intent.ACTION_USER_BACKGROUND);
boolean appCameToForeground = intent.getAction().equals(Intent.ACTION_USER_FOREGROUND);
// TODO MultiUser
if (appSentToBackground) {
log("App going to background");
try {
// Release all resources
if (emdkManager != null) {
emdkManager.release();
emdkManager = null;
}
} catch (Throwable e) {
e.printStackTrace();
}
}
if (appCameToForeground) {
log("App coming to foreground");
// Setting objects to null if background task are interrupted.
if(scanner != null)
scanner = null;
if(barcodeManager != null)
barcodeManager = null;
if(emdkManager != null)
emdkManager = null;
EMDKResults results = EMDKManager.getEMDKManager(getApplicationContext(), MainActivity.this);
// Use a final variable if MainActivity.this (above) fails.
// If result == SUCCESS, onOpened is called
// and scanner object is reacquired
if (results.statusCode != EMDKResults.STATUS_CODE.SUCCESS) {
return;
}
}
}
};
@Override
protected void onDestroy() {
super.onDestroy();
try {
// Release all resources
if (emdkManager != null) {
emdkManager.release();
emdkManager = null;
}
}
catch (Throwable throwable)
{
throwable.printStackTrace();
}
}
@Override
public void onOpened(EMDKManager emdkManager) {
this.emdkManager = emdkManager;
log("Initializing EMDK.. Please wait..");
// Acquire barcode manager resources
barcodeManager = (BarcodeManager) emdkManager.getInstance(FEATURE_TYPE.BARCODE);
if(barcodeManager == null)
{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
barcodeManager = (BarcodeManager) emdkManager.getInstance(FEATURE_TYPE.BARCODE);
}
// Add connection listener
if (barcodeManager != null) {
barcodeManager.addConnectionListener(this);
initScanner();
}
}
@Override
public void onClosed() {
try {
if (emdkManager != null) {
// Release all the resources
emdkManager.release();
emdkManager = null;
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private void initScanner() {
if (scanner == null) {
scanner = barcodeManager.getDevice(BarcodeManager.DeviceIdentifier.DEFAULT);
if (scanner != null) {
scanner.addDataListener(this);
scanner.addStatusListener(this);
try {
scanner.enable();
} catch (ScannerException e) {
}
}
}
}
@Override
public void onData(ScanDataCollection scanDataCollection) {
if ((scanDataCollection != null) && (scanDataCollection.getResult() == ScannerResults.SUCCESS)) {
ArrayList<ScanDataCollection.ScanData> scanData = scanDataCollection.getScanData();
for(ScanDataCollection.ScanData data : scanData) {
log("onData: " + data.getData());
}
}
}
@Override
public void onStatus(StatusData statusData) {
StatusData.ScannerStates state = statusData.getState();
String statusString = statusData.getFriendlyName()+" is " + state.toString().toLowerCase();
log("Status: "+statusString);
switch(state) {
case IDLE:
try {
scanner.read();
} catch (ScannerException e) {
e.printStackTrace();
log("Error: " + e.getMessage());
}
break;
}
}
@Override
public void onConnectionChange(ScannerInfo scannerInfo, ConnectionState connectionState) {
}
private void log(String message)
{
Log.d("TAG","#EMDKMultiuser# " + message);
}
}