I am developing an Android inventory app in Kotlin for Zebra TC21 devices, and I would like to configure a Datawedge profile programmatically. I need to scan qr codes with the integrated scanner, and RFID tags with a Zebra RFD4031. I would like the scanned data to be transmitted by "Intent output" with Broadcast mode. I also want the "key output" to be disabled.
I tried with this code:
class DatawedgeConfig {
val baseConfig = createBaseConfig()
fun initialize(context: Context) {
try {
createProfile(context)
configureProfile(context)
configureInput(context)
configureOutput(context)
Log.d("DatawedgeConfig", "DataWedge initialized successfully")
} catch (e: Exception) {
Log.e("DatawedgeConfig", "Error initializing DataWedge", e)
}
}
private fun createBaseConfig(): Bundle {
return Bundle().apply {
putString("PROFILE_NAME", DATAWEDGE_PROFILE_NAME)
putString("PROFILE_ENABLED", "true")
putString("CONFIG_MODE", "UPDATE")
}
}
fun createProfile(context: Context) {
val intent = Intent()
intent.action = "com.symbol.datawedge.api.ACTION"
intent.putExtra("com.symbol.datawedge.api.CREATE_PROFILE", DATAWEDGE_PROFILE_NAME)
try {
context.sendBroadcast(intent)
Log.d("DatawedgeConfig", "Profile created successfully")
} catch (e: Exception) {
Log.e("DatawedgeConfig", "Error creating profile", e)
}
}
fun configureProfile(context: Context) {
val intent = Intent()
intent.action = "com.symbol.datawedge.api.ACTION"
intent.putExtra("com.symbol.datawedge.api.SET_CONFIG", Bundle().apply {
baseConfig.putParcelableArray("APP_LIST", arrayOf(Bundle().apply {
putString("PACKAGE_NAME", context.packageName)
putStringArray("ACTIVITY_LIST", arrayOf("*"))
}))
})
Log.d("DataWedgeConfig", "Configuring profile: $baseConfig")
try {
context.sendBroadcast(intent)
Log.d("DatawedgeConfig", "Profile configured successfully (PACKAGE_NAME : ${context.packageName})")
} catch (e: Exception) {
Log.e("DatawedgeConfig", "Error configuring profile", e)
}
}
fun configureInput(context: Context) {
val intent = Intent()
intent.action = "com.symbol.datawedge.api.ACTION"
intent.putExtra("com.symbol.datawedge.api.SET_CONFIG", Bundle().apply {
baseConfig.putParcelableArray("PLUGIN_CONFIG", arrayOf(Bundle().apply {
putString("PLUGIN_NAME", "BARCODE")
putString("RESET_CONFIG", "true")
putBundle("PARAM_LIST", Bundle().apply {
putString("scanner_selection", "auto")
putString("decoder_rfid", "true")
putString("decoder_qr_code", "true")
})
}))
})
try {
context.sendBroadcast(intent)
Log.d("DatawedgeConfig", "Input configured successfully")
} catch (e: Exception) {
Log.e("DatawedgeConfig", "Error configuring input", e)
}
}
fun configureOutput(context: Context) {
val intent = Intent()
intent.action = "com.symbol.datawedge.api.ACTION"
intent.putExtra("com.symbol.datawedge.api.SET_CONFIG", Bundle().apply {
baseConfig.putParcelableArray("PLUGIN_CONFIG", arrayOf(Bundle().apply {
putString("PLUGIN_NAME", "INTENT")
putString("RESET_CONFIG", "true")
putBundle("PARAM_LIST", Bundle().apply {
putString("intent_output_enabled", "true")
putString("intent_action", DATAWEDGE_ACTION)
putString("intent_delivery", "2")
})
}))
})
try {
context.sendBroadcast(intent)
Log.d("DatawedgeConfig", "Output configured successfully")
} catch (e: Exception) {
Log.e("DatawedgeConfig", "Error configuring output", e)
}
}
}
The profile is actually created if it doesn't exist, but none of the options in the "SET_CONFIG" bundle is apllied. So, my app isn't associated with the created profile, and the intent output isn't neither enabled nor configured with the given values.
I don't understand why.
1 Replies
I've finally found a solution. I share it for those who'd be interested:
```kotlin
import android.content.Context
import android.content.Intent
import android.os.Bundle
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class DWConfig @Inject constructor(
@ApplicationContext private val context: Context,
) {
val setConfigBundle = Bundle().apply {
putString("PROFILE_NAME", DATAWEDGE_PROFILE_NAME)
putString("PROFILE_ENABLED", "true")
putString("CONFIG_MODE", "CREATE_IF_NOT_EXIST")
}
val appConfig = Bundle().apply {
putString("PACKAGE_NAME", context.packageName)
putStringArray(
"ACTIVITY_LIST", arrayOf(
"${context.packageName}.MainActivity",
)
)
}
val barcodeParamList = Bundle().apply {
putString("scanner_input_enabled", "true")
putString("scanner_selection", "auto")
putString("charset_name", "ISO-8859-1")
putString("auto_charset_preferred_order", "UTF-8;GB2312")
putString("auto_charset_failure_option", "UTF-8")
putString("volume_slider_type", "3")
}
val barcodeConfigBundle = Bundle().apply {
putString("PLUGIN_NAME", "BARCODE")
putString("RESET_CONFIG", "true")
}
val intentParamList = Bundle().apply {
putString("intent_output_enabled", "true")
putString("intent_action", DATAWEDGE_INTENT_ACTION)
putString("intent_delivery", "2")
}
val intentConfigBundle = Bundle().apply {
putString("PLUGIN_NAME", "INTENT")
putString("RESET_CONFIG", "true")
}
val rfidParamList = Bundle().apply {
putString("rfid_input_enabled", "true")
putString("rfid_beeper_enable", "false")
putString("rfid_led_enable", "true")
putString("rfid_antenna_transmit_power", "30")
putString("rfid_memory_bank", "3")
putString("rfid_session", "1")
putString("rfid_trigger_mode", "0")
putString("rfid_filter_duplicate_tags", "true")
putString("rfid_hardware_trigger_enabled", "true")
putString("rfid_tag_read_duration", "250")
}
val rfidConfigBundle = Bundle().apply {
putString("PLUGIN_NAME", "RFID")
putString("RESET_CONFIG", "true")
}
val keystrokeParamList = Bundle().apply {
putString("keystroke_output_enabled", "false")
}
val keystrokeConfigBundle = Bundle().apply {
putString("PLUGIN_NAME", "KEYSTROKE")
putString("RESET_CONFIG", "true")
}
private fun setAppList() {
setConfigBundle.putParcelableArray(
"APP_LIST", arrayOf(
appConfig
)
)
}
private fun setPluginConfig() {
setConfigBundle.remove("PLUGIN_CONFIG")
barcodeConfigBundle.putBundle("PARAM_LIST", barcodeParamList)
intentConfigBundle.putBundle("PARAM_LIST", intentParamList)
rfidConfigBundle.putBundle("PARAM_LIST", rfidParamList)
keystrokeConfigBundle.putBundle("PARAM_LIST", keystrokeParamList)
setConfigBundle.putParcelableArrayList(
"PLUGIN_CONFIG", arrayListOf(
barcodeConfigBundle,
intentConfigBundle,
rfidConfigBundle,
keystrokeConfigBundle
)
)
}
private fun sendConfig() {
val intent = Intent().apply {
action = "com.symbol.datawedge.api.ACTION"
putExtra("com.symbol.datawedge.api.SET_CONFIG", setConfigBundle)
}
context.sendBroadcast(intent)
}
fun initialize() : Boolean {
try {
setAppList()
setPluginConfig()
sendConfig()
return true
} catch (e: Exception) {
Log.e("DWConfig", "Error initializing DataWedge", e)
return false
}
}
}
```
I call `initialize()` method during the launch of my app:
```kotlin
@HiltViewModel
class MainViewModel @Inject constructor(
private val dwConfig: DWConfig
) : ViewModel() {
fun initializeDataWedge(): Boolean {
return dwConfig.initialize()
}
...
}
```
```kotlin
@HiltAndroidApp
class MainApplication : Application() {
@Composable
fun App(activity: MainActivity, mainViewModel: MainViewModel) {
LaunchedEffect(Unit) {
val dataWedgeJob = async { mainViewModel.initializeDataWedge() }
...
dataWedgeJob.await()
...
}
```
I found most of the informations that I needed here (unfortunately, all the examples are written in Java) :
https://techdocs.zebra.com/datawedge/13-0/guide/api/setconfig/
Almost all the parameters that you can configure in the Datawedge App are referenced here with their ids and their possible values that you can set programmatically.