Frequently Asked Questions
Why am I not receiving intents broadcasted by IntentWedge?
You are likely using an implicit broadcast. Google introduced several limitations regarding implicit broadcasts in Android 8 in order to improve dispatching performance. According to the Android documentation:
Android 8.0 (API level 26) makes these limitations more stringent.
- Apps that target Android 8.0 or higher can no longer register broadcast receivers for implicit broadcasts in their manifest. An implicit broadcast is a broadcast that does not target that app specifically. For example, ACTION_PACKAGE_REPLACED is an implicit broadcast, since it is sent to all registered listeners, letting them know that some package on the device was replaced. However, ACTION_MY_PACKAGE_REPLACED is not an implicit broadcast, since it is sent only to the app whose package was replaced, no matter how many other apps have registered listeners for that broadcast.
- Apps can continue to register for explicit broadcasts in their manifests.
- Apps can use Context.registerReceiver() at runtime to register a receiver for any broadcast, whether implicit or explicit.
- Broadcasts that require a signature permission are exempted from this restriction, since these broadcasts are only sent to apps that are signed with the same certificate, not to all the apps on the device.
So, if your app registers itself to receive the intent used by IntentWedge in the Manifest, this approach works properly until Android 7. But, if the app follows the new Google guidelines regarding broadcast limitations introduced in Android 8, that is to register the App to receive intents at runtime with the Context.registerReceiver() call, this feature will work as expected for all Android versions.
Is the Datalogic SDK compatible with ProGuard obfuscation?
Yes. However, in order to ensure your app builds correctly while using ProGuard obfuscation, you will need to edit your ProGuard rules file. Add the following rules to ensure R8 includes all the code it needs to correctly use the Datalogic SDK:
-keep class com.datalogic.cradle.** { *; }
-keep class com.datalogic.decode.** { *; }
-keep class com.datalogic.device.** { *; }
-keep class com.datalogic.extension.** { *; }
-keep class com.datalogic.softspot.** { *; }
How can I receive barcode data in my app?
Register a ReadListener to receive read events on successful barcode reads:
- Kotlin
- Java
override fun onResume() {
super.onResume()
try {
if (decoder == null) {
decoder = BarcodeManager()
listener = ReadListener { decodeResult ->
mBarcodeText.text = decodeResult.text
}
}
decoder!!.addReadListener(listener)
} catch (e : DecodeException) {
e.printStackTrace()
}
}
@Override
protected void onResume() {
super.onResume();
try {
if (decoder == null) {
decoder = new BarcodeManager();
listener = new ReadListener() {
@Override
public void onRead(DecodeResult decodeResult) {
mBarcodeText.setText(decodeResult.getText());
}
};
decoder.addReadListener(listener);
}
} catch (DecodeException e) {
e.printStackTrace();
}
}
Unregister the ReadListener in your Activity.onPause()
:
- Kotlin
- Java
override fun onPause() {
super.onPause()
if (decoder != null) {
try {
decoder!!.removeReadListener(listener)
decoder = null
} catch (e: Exception) {
e.printStackTrace()
}
}
}
@Override
protected void onPause() {
super.onPause();
if (decoder != null) {
try {
decoder.removeReadListener(listener);
decoder = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
The actual barcode scanning is started via any physical scan trigger on the device. Though to start scanning when a button on the application is pressed,you need to call BarcodeManager.startDecode().
How can I configure Decoder properties?
To configure the decoder properties, you need to instantiate BarcodeManager and get a ScannerProperties reference.
- Kotlin
- Java
var manager: BarcodeManager? = null
var configuration: ScannerProperties? = null
try {
manager = BarcodeManager()
} catch (e: DecodeException) {
e.printStackTrace()
}
configuration = ScannerProperties.edit(manager)
BarcodeManager manager = null;
ScannerProperties configuration = null;
try {
manager = new BarcodeManager();
} catch (DecodeException e) {
e.printStackTrace();
}
configuration = ScannerProperties.edit(manager);
Properties are organized hierarchically. Each property has the method set
that requires a different argument depending on the property type (i.e.: int, boolean, String, etc...):
- Kotlin
- Java
configuration = ScannerProperties.edit(manager)
configuration!!.code39.enable.set(true);
configuration!!.code39.enableChecksum.set(false);
configuration!!.code39.fullAscii.set(true);
configuration!!.code39.Length1.set(20);
configuration!!.code39.userID.set('x');
if (configuration!!.qrCode.isSupported()) {
configuration!!.qrCode.enable.set(false);
}
configuration.code39.enable.set(true);
configuration.code39.enableChecksum.set(false);
configuration.code39.fullAscii.set(true);
configuration.code39.Length1.set(20);
configuration.code39.userID.set('x');
if (configuration.qrCode.isSupported()) {
configuration.qrCode.enable.set(false);
}
For the configuration to be actually applied, you must call the method ScannerProperties.store.
- Kotlin
- Java
val errorCode = configuration!!.store(manager, true)
try {
configuration.store(manager, true);
} catch (ConfigException e) {
e.printStackTrace();
return;
}
How can I retrieve device information and control other device features?
The Datalogic Android SDK provides APIs for many useful operations that can't be done using the standard AOSP SDK.
Info
Datalogic SDK provides advanced information about the device in the SYSTEM class, which exposes Wi-Fi type, keyboard type and others as static members. Example usage:
- Kotlin
- Java
com.datalogic.device.info.SYSTEM.SDK_VERSION_INT
com.datalogic.device.info.SYSTEM.SDK_VERSION_INT;
Power
To get information about the battery, Android broadcasts the Intent
Intent.ACTION_BATTERY_CHANGED() which carries information in its extra properties. The intent is fired every time the status of the battery changes. Once you register a receiver, notice that this particular behavior happens because the battery intent is a STICKY one: Content.sendStickyBroadcast().
- Kotlin
- Java
var currentBatteryStatus: Intent? =
registerReceiver(null, IntentFilter(
Intent.ACTION_BATTERY_CHANGED)
)
Intent currentBatteryStatus =
registerReceiver(null, new IntentFilter(
Intent.ACTION_BATTERY_CHANGED)
);
Location
The standard Android SDK does not allow toggling of the Location services (GPS, network, etc...) thus an application must ask the user to do it manually. Datalogic SDK overcomes this limitation by providing the LocationManager class, which there is an example of below:
- Kotlin
- Java
try {
val loc: LocationManager? = LocationManager()
loc!!.setLocationMode(if (enable) LocationMode.SENSORS_AND_NETWORK else LocationMode.OFF)
} catch (e1: DeviceException) {
e.printStackTrace()
}
com.datalogic.device.location.LocationManager loc = null;
try {
loc = new com.datalogic.device.location.LocationManager();
loc.setLocationMode(enable ? LocationMode.SENSORS_AND_NETWORK : LocationMode.OFF);
} catch (DeviceException e) {
e.printStackTrace();
}
NFC
Standard Android SDK doesn't allow to turn on or off the NFC adapter, thus an application must ask to the user to manually do it. Datalogic SDK overcomes this limit providing the NfcManager class.
- Kotlin
- Java
val error = com.datalogic.device.nfc.NfcManager().enableNfcAdapter(enable)
if (error != DeviceException.SUCCESS) {
Log.e(javaClass.name, "Error while setting NFC", ErrorManager.getLastError())
}
int error = new com.datalogic.device.nfc.NfcManager().enableNfcAdapter(enable);
if(error != DeviceException.SUCCESS) {
Log.e(getClass().getName(), "Error while setting NFC", ErrorManager.getLastError());
}
LEDs
Datalogic SDK allows one to control LEDs on the device. The standard Android APIs for controlling the notification LED via the notifications system still works, though you are limited to 1 LED. Datalogic devices may have more LEDs, and it is easier to control them using the LedManager than the standard API.
- Kotlin
- Java
LedManager led = LedManager();
led.blinkLed(Led.LED_GREEN_SPOT, 1, 500, 500)
LedManager led = new LedManager();
led.blinkLed(Led.LED_GREEN_SPOT, 1, 500, 500);
Please notice that not all LEDs on a device can be freely controlled by a user application, as some are reserved to the system.
Touch
The TouchManager class can be used to lock the touchscreen.
- Kotlin
- Java
val tm = TouchManager()
tm.lockInput(true)
Thread.sleep(2000)
tm.lockInput(false)
TouchManager tm = new TouchManager();
tm.lockInput(true);
Thread.sleep(2000);
tm.lockInput(false);
Sleep and Wakeup
The PowerManager class allows to configure the screen off timeout and the wakeup sources of the device.
The SuspendTimeout can be set with a condition: the device running on battery or the device plugged to a power source, the function PowerManager.setSuspendTimeout() has a boolean argument for it.
- Kotlin
- Java
val pm = PowerManager()
pm.setSuspendTimeout(SuspendTimeout.MINUTES_5, false) // battery
pm.setSuspendTimeout(SuspendTimeout.NEVER, true) // ext power
PowerManager pm = new PowerManager();
pm.setSuspendTimeout(SuspendTimeout.MINUTES_5, false); // battery
pm.setSuspendTimeout(SuspendTimeout.NEVER, true); // ext power
Please notice that not all the WakeupSources available in the SDK are supported by a device, thus is better to check for the support before enabling/disabling them.
- Kotlin
- Java
if (pm.isWakeupSupported(WakeupSource.TRIG_LEFT) &&
!pm.isWakeupActive(WakeupSource.TRIG_LEFT)) {
pm.activateWakeup(WakeupSource.TRIG_LEFT)
}
if (pm.isWakeupSupported(WakeupSource.TRIG_LEFT) &&
!pm.isWakeupActive(WakeupSource.TRIG_LEFT)) {
pm.activateWakeup(WakeupSource.TRIG_LEFT);
}
Reset
With the PowerManager class it is possible to perform several type of resets and reboot of the device. BootType.ENTERPRISE_RESET and BootType.FACTORY_RESET reset types clear the configuration of the device setting it to a custom one or to the out-of-the-box one respectively, while BootType.RESET is a software reboot of the device.