Scanning when app is minimised
I have a problem which I am explaining below:
I want to make an app that can keep scanning even when it is minimized. So I followed the git example BarcodeSample1 and modified the activity. I have attached the MainActivity (which I modified). Basically I removed the trigger and decoders block from it which I believe I do not need for now. All I need is that even if my app is minimised it can capture the scans.
The app is working fine. It is providing me the scanned data even when it is foreground or minimized.
BUT, when I kill my app, the scanner only works once and then it dies. Now even if I open the DWDemo app, the scanner does not work at all. If I open my app again, it starts working and again dies when I kill it.
Somehow my application is not releasing the scanner and it dies and lives with my app.
I HAVE ATTACHED MY MAIN ACTIVITY
I am updating the thread with our conversation over email.
I am using the git example BarcodeSample1 as it fulfills my requirement and scans the barcodes even when the device is locked or if any other application is on top of it, perfect.
The problem I am facing is that the device is kept locked for some time (10-15 seconds), the scanner dies and just shows a very weak orange light. It does not scan either.
Can you please guide me why this might be happening?
The scanner is designed to go to sleep when running in the background and the app itself will also go to sleep. You might try holding a wake lock and whitelisting your app against Doze Mode – I have not tried it myself with scanning but this might work. Please see https://developer.zebra.com/blog/keeping-your-android-application-runnin... for more information.
I tried the method to whitelist my app. The one with permission in manifest and using the profile manager as well.
My app is not using any profile. So I created a profile and in the emdk plugin in android studio, I selected the power manager and disabled the doze mode. But still my scanner died.
If I use the EMDK profile method and broadcast to listen to the scans, like I am doing in one of the other apps, can I listen to the scans while app is in background, device is locked as well? Meaning my application will keep the scanner to itself. I tried the datawedge-kotlin sample, and it does not scan in background, even though the broadcast receiver is not unregistered in onPause.
> "can I listen to the scans while app is in background, device is locked as well?"
Not typically, if the app is scanning in the background we expect the Bluetooth scanner to be used. Bluetooth is exempt from doze mode so is probably a special case.
Android is aggressive in not allowing applications to run in the background. The behaviour you observe (“I tried the datawedge-kotlin sample, and it does not scan in background, even though the broadcast receiver is not unregistered in onPause”) is likely caused by Android stopping your application running when in the background.
You face an uphill battle trying to exempt yourself from these background restrictions and the scanner is not designed to work when the device is in standby.
Why do you want to scan when the device is locked? If I understand your use case I might be able to suggest something else.
>"You face an uphill battle trying to exempt yourself from these background restrictions and the scanner is not designed to work when the device is in standby".
This I understood only in a few days :D
>"Why do you want to scan when the device is locked? If I understand your use case I might be able to suggest something else."
Our client uses the application to send the scanned values to the server. They have a webpage that is always updating based on the scans. So they want that webpage to be on top and keep scanning using our application. Since every scan is sent on the server, they are able to see the updated data on their webpage. So this is why they need our application to work in the background, keeping the scanner to itself.
Working in a locked device is something that they need for their field employees.
But if the devices do not allow us to perform such actions, maybe I can try some other workaround to solve their problem :)
So if I was approaching this I would probably do the following:
Have the scan button wake up the device from the sleep state. You can specify a wake-up source using the MX power manager, https://techdocs.zebra.com/mx/powermgr/, but that only works on our latest devices running a recent patch. I’m unsure which devices you are using. The device can still be locked behind a keyguard.
Configure DataWedge to call startService when a barcode is scanned by modifying the Intent Output plugin, https://techdocs.zebra.com/datawedge/7-6/guide/output/intent/. This is something you would configure on the default profile so DW calls startService regardless of the foreground app. You may also need to configure this on the ‘Launcher’ profile.
In your application, register a service (the service that is invoked by DataWedge’s startService) to do the work of sending scans to the server.
Does that make sense? A service is used because an application will be invoked even if it is not running (unlike a broadcast receiver). The main problem with the above may be whether your device supports wake-up sources.
I haven’t tried the above, it is just my initial idea :)
is there any sample with startService output in DW?
I could find your example of a broadcast intent and the zebra website has the one with startActivity.
The tried to change the data wedge sample locally.
Instead if registering the receiver and setting observer in MainActivity, but how am I supposed to get the data? in onBind(intent)?
Please take a look at https://github.com/Zebra/samples-datawedge/tree/master/DataWedge-API-Exe..., specifically https://github.com/Zebra/samples-datawedge/blob/master/DataWedge-API-Exe... which is registered to listen for DataWedge intents at https://github.com/Zebra/samples-datawedge/blob/master/DataWedge-API-Exe.... That example sends data to the MainActivity via a broadcast receiver but you should be able to communicate to your server from the onHandleIntent() method.
Hi Prakhar, once an application acquires the scanner no other application is able to acquire the scanner until it is released. That also means DataWedge is not able to acquire the scanner once your app acquires it. After your app is killed it looks like the scanner is never being released - in your source code I notice you have commented the code out from onDestroy() - adding that deinitScanner() back into onDestroy() may mitigate this issue but I know onDestroy() is not guaranteed to be called.
The best solution may be for you to use DataWedge to listen for scans. There is a Kotlin sample app that uses DataWedge at https://github.com/darryncampbell/DataWedgeKotlin but note this app unregisters the broadcast receiver when the app is minimised... you would want to keep the broadcast receiver registered when your app is in the background (or do something more clever like move to having a service handle the scans)