androidkotlinandroid-bluetoothandroid-runonuithread

How to pass data that changes real-time from activity to fragment?


I am currently reading data from a Bluetooth Sensor, hence the data changes in real-time and continuously changes. I have stored the data in a variable: liveData:ByteArray

Now I am trying to send liveData from MainActivity to Sensordisplayfragment.

UPDATE

Based on @CTD's comment, this is what I have tried, unfortunately I do not have much knowledge on viewModel, and online research is just confusing as there seems to be many methods to implement a viewModel.

In my MainActivity class where variable liveData is stored:

val model:MyViewModel by viewModels()
    private fun processLiveData(liveData : ByteArray){
        livedata = liveData
        model.uploadData(livedata)
    }

In MyViewModel.class where the viewModel is at:

class MyViewModel: ViewModel() {
    private val realtimedata = MutableLiveData<ByteArray>()

    fun uploadData(data:ByteArray){
        realtimedata.value = data
    }

    fun loadData():LiveData<ByteArray>{
        return realtimedata
    }
}

Finally, in my Sensordisplay fragment where I am fetching the data:

val model:MyViewModel by viewModels()

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    model.loadData().observe(viewLifecycleOwner,Observer<ByteArray>{
        passandprocessLiveData(it)
    })
    return inflater.inflate(R.layout.sensordisplay, container, false)
}

override fun onResume(){
    activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
    model.loadData().observe(viewLifecycleOwner,Observer<ByteArray>{
        passandprocessLiveData(it)
    })
    super.onResume()
}

fun passandprocessLiveData(data:Bytearray){
    //extract information from data and make 
    //cardviews move in realtime according to the extracted data
    }

Unfortunately,nothing is getting transferred and my cardviews are not moving. I can guarantee there is no error in the moving of the cardview codes. Anyone able to advice on what I can add? Apparently there is an init() function that I need to use.


Solution

  • class MyViewModel : ViewModel() {
        private val realtimedata = MutableLiveData<ByteArray>()
    
        val sensorData: LiveData<ByteArray> = realtimedata
    
        fun update(data: ByteArray){
            realtimedata.value = data
        }
    }
    
    class MainActivity: Activity() {
    
        private val viewModel: MyViewModel by viewModels()
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            bluetoothSensorCallBack { data ->
                // Update the realtimedata 
                viewModel.update(data)
            }
        }
    }
    
    class SensordisplayFragment : Fragment() {
    
        // Use the 'by activityViewModels()' Kotlin property delegate
        // from the fragment-ktx artifact
        private val model: MyViewModel by activityViewModels()
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            model.sensorData.observe(viewLifecycleOwner, Observer<ByteArray> { data ->
                // Update the UI
            })
        }
    }