How to configure a Datawedge profile programatically in an Android Kotlin app?

P Pierrick Valentin 1 week 3 days ago
21 1 0

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.

Please Register or Login to post a reply

1 Replies

P Pierrick Valentin

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.

CONTACT
Can’t find what you’re looking for?