如何将位置数据从LocationService推送到HomeViewModel?

huangapple go评论70阅读模式
英文:

How can i push location data from LocationService to HomeViewModel?

问题

我正在尝试将位置数据从LocationService推送到HomeViewModel。我试图使用Dagger来注入这些数据,但该值始终为null。我不知道如何做。

我的LocationService代码如下:

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"
    }
}

我还在以下GitHub链接上留下了这个项目的链接:https://github.com/DawidSiudeja/RunTracker/tree/main/app/src/main/java/com/example/runtracker

英文:

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&lt;Pair&lt;String, String&gt;&gt;()
val locationLiveData: LiveData&lt;Pair&lt;String, String&gt;&gt; = _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 -&gt; start()
ACTION_STOP -&gt; stop()
}
return super.onStartCommand(intent, flags, startId)
}
private fun start() {
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle(&quot;Tracking location...&quot;)
.setContentText(&quot;Location: null&quot;)
.setSmallIcon(R.drawable.ic_launcher_background)
.setOngoing(true)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
locationClient.getLocationUpdates(5000L)
.catch { e-&gt; e.printStackTrace() }
.onEach { location -&gt;
val lat = location.latitude.toString()
val long = location.longitude.toString()
_locationLiveData.postValue(Pair(lat, long))
Log.d(&quot;LocationT&quot;, &quot;LocationService: &quot; + (locationLiveData.value?.first ?: &quot;Dupa0&quot;))
val updatedNotification = notification.setContentText(
&quot;Location: $lat, $long&quot;
)
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 = &quot;ACTION_START&quot;
const val ACTION_STOP = &quot;ACTION_STOP&quot;
} }

I also leave link to this projecy on Github: https://github.com/DawidSiudeja/RunTracker/tree/main/app/src/main/java/com/example/runtracker

答案1

得分: 1

创建变量在您的服务的伴生对象块内

class LocationService: Service() {

    private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
    private lateinit var locationClient: LocationClient

    companion object{
    val locationLiveData = MutableLiveData<Pair<String, String>>()
     }
 }

然后在您的活动/片段中观察它

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: Pair<String, String>){
   //使用纬度和经度值来更新地图
 }

}
英文:

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&lt;Pair&lt;String, String&gt;&gt;()
}
}

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&lt;String,String&gt;){
//use the lat lng value to update the map
}
}

huangapple
  • 本文由 发表于 2023年7月18日 03:35:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76707603.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定