I'm trying to push location data from LocationService to HomeViewModel. I was trying to use Dagger to inject this data, but the value is always null. I don't have any idea how to do it.
My LocationService Code:
class LocationService: Service() {
private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
private lateinit var locationClient: LocationClient
private val _locationLiveData = MutableLiveData<Pair<String, String>>()
val locationLiveData: LiveData<Pair<String, String>> = _locationLiveData
override fun onBind(p0: Intent?): IBinder? {
return null
}
override fun onCreate() {
super.onCreate()
locationClient = DefaultLocationClient(
applicationContext,
LocationServices.getFusedLocationProviderClient(applicationContext)
)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
when(intent?.action) {
ACTION_START -> start()
ACTION_STOP -> stop()
}
return super.onStartCommand(intent, flags, startId)
}
private fun start() {
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Tracking location...")
.setContentText("Location: null")
.setSmallIcon(R.drawable.ic_launcher_background)
.setOngoing(true)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
locationClient.getLocationUpdates(5000L)
.catch { e-> e.printStackTrace() }
.onEach { location ->
val lat = location.latitude.toString()
val long = location.longitude.toString()
_locationLiveData.postValue(Pair(lat, long))
Log.d("LocationT", "LocationService: " + (locationLiveData.value?.first ?: "Dupa0"))
val updatedNotification = notification.setContentText(
"Location: $lat, $long"
)
notificationManager.notify(1, updatedNotification.build())
}.launchIn(serviceScope)
startForeground(1, notification.build())
}
private fun stop() {
stopForeground(true)
stopSelf()
}
override fun onDestroy() {
super.onDestroy()
serviceScope.cancel()
}
companion object {
const val ACTION_START = "ACTION_START"
const val ACTION_STOP = "ACTION_STOP"
} }
I also leave link to this projecy on Github: https://github.com/DawidSiudeja/RunTracker/tree/main/app/src/main/java/com/example/runtracker
Create the variables inside a companion object block of your service
class LocationService: Service() {
private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
private lateinit var locationClient: LocationClient
companion object{
val locationLiveData = MutableLiveData<Pair<String, String>>()
}
}
And the in your activity/fragment observe it as
class TrackingFragment : Fragment(R.layout.fragment_tracking) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val mapViewBundle = savedInstanceState?.getBundle(MAP_VIEW_BUNDLE_KEY)
mapView.onCreate(mapViewBundle)
subscribeToObservers()
}
private fun subscribeToObservers() {
LocationService.locationLiveData.observe(viewLifecycleOwner, Observer {
updateTracking(it)
})
}
private fun updateTracking(Pair<String,String>){
//use the lat lng value to update the map
}
}