Skip to content

Commit

Permalink
feat: replace LocationLiveData with MapLocationFlow
Browse files Browse the repository at this point in the history
  • Loading branch information
growse committed Oct 7, 2024
1 parent e1508fd commit 6c9475b
Show file tree
Hide file tree
Showing 10 changed files with 210 additions and 192 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import com.google.android.gms.maps.CameraUpdate
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
Expand All @@ -28,6 +28,8 @@ import com.google.android.gms.maps.model.CircleOptions
import com.google.android.gms.maps.model.MapStyleOptions
import com.google.android.gms.maps.model.Marker
import com.google.android.gms.maps.model.MarkerOptions
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import org.owntracks.android.R
import org.owntracks.android.data.waypoints.WaypointModel
import org.owntracks.android.databinding.GoogleMapFragmentBinding
Expand Down Expand Up @@ -57,20 +59,23 @@ internal constructor(

private val googleMapLocationSource: LocationSource by lazy {
object : LocationSource {
private var locationObserver: Observer<Location>? = null
private var collectorJob: Job? = null

override fun activate(onLocationChangedListener: LocationSource.OnLocationChangedListener) {
locationObserver =
Observer { location: Location ->
onLocationObserved(location) {
onLocationChangedListener.onLocationChanged(location)
}
Timber.tag("LocationFlow").i("GoogleMapFragment activate")
collectorJob =
lifecycleScope.launch {
viewModel.currentLocationFlow.collect { location: Location ->
onLocationObserved(location) {
onLocationChangedListener.onLocationChanged(location)
}
.apply { viewModel.currentLocation.observe(viewLifecycleOwner, this) }
}
}
}

override fun deactivate() {
locationObserver?.run(viewModel.currentLocation::removeObserver)
Timber.tag("LocationFlow").i("Google MapFragment stopLocationProvider")
collectorJob?.cancel()
}
}
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package org.owntracks.android.ui.map

import android.annotation.SuppressLint
import android.content.Context
import android.location.Location
import android.os.Looper
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import java.time.Duration
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.shareIn
import org.owntracks.android.gms.location.toGMSLocationRequest
import org.owntracks.android.location.LocationRequest
import org.owntracks.android.location.LocatorPriority
import timber.log.Timber

class MapLocationFlow(private val locationProviderClient: FusedLocationProviderClient) {
constructor(
context: Context,
) : this(LocationServices.getFusedLocationProviderClient(context))

init {
Timber.tag("LocationFlow").w("Init locationFlow")
}

@SuppressLint("MissingPermission")
fun getLocationFlow(coroutineScope: CoroutineScope): Flow<Location> =
callbackFlow {
val locationCallback =
object : LocationCallback() {
override fun onLocationResult(location: LocationResult) {
location.lastLocation?.run(::trySend)
}
}
locationProviderClient.apply {
requestLocationUpdates(
LocationRequest(
smallestDisplacement = 1f,
priority = LocatorPriority.HighAccuracy,
interval = Duration.ofSeconds(2),
waitForAccurateLocation = false)
.toGMSLocationRequest(),
locationCallback,
Looper.getMainLooper())
.addOnCompleteListener {
Timber.d(
"LocationLiveData location update request completed: " +
"Success=${it.isSuccessful} Cancelled=${it.isCanceled}")
Timber.tag("LocationFlow").w("Starting locationFlow")
}
awaitClose {
locationProviderClient
.removeLocationUpdates(locationCallback)
.addOnCompleteListener {
Timber.d(
"LocationLiveData removing location updates completed: " +
"Success=${it.isSuccessful} Cancelled=${it.isCanceled}")
Timber.tag("LocationFlow").w("Stopping locationFlow")
}
}
}
}
.shareIn(
coroutineScope, SharingStarted.WhileSubscribed(stopTimeoutMillis = 2000), replay = 0)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.owntracks.android.di

import android.content.Context
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ViewModelComponent
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.scopes.ViewModelScoped
import org.owntracks.android.ui.map.MapLocationFlow

@InstallIn(ViewModelComponent::class)
@Module
class CurrentLocationFlowProviderModule {
@Provides
@ViewModelScoped
fun getCurrentLocationFlow(@ApplicationContext applicationContext: Context) =
MapLocationFlow(applicationContext)
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ import androidx.core.widget.ImageViewCompat
import androidx.databinding.BindingAdapter
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.commit
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.dialog.MaterialAlertDialogBuilder
Expand Down Expand Up @@ -242,7 +244,7 @@ class MapActivity :
}
backPressedCallback =
onBackPressedDispatcher.addCallback(this, false) {
Timber.w("ARSE")
Timber.w("LocationFlow")
when (bottomSheetBehavior?.state) {
BottomSheetBehavior.STATE_COLLAPSED -> {
setBottomSheetHidden()
Expand Down Expand Up @@ -274,14 +276,16 @@ class MapActivity :
setBottomSheetCollapsed()
}
}
viewModel.currentLocation.observe(this) { location ->
if (location == null) {
disableLocationMenus()
} else {
enableLocationMenus()
binding.vm?.run { updateActiveContactDistanceAndBearing(location) }

lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.currentLocationFlow.collect { location ->
enableLocationMenus()
viewModel.updateActiveContactDistanceAndBearing(location)
}
}
}

viewModel.currentMonitoringMode.observe(this) { updateMonitoringModeMenu() }

startService(this)
Expand Down
Loading

0 comments on commit 6c9475b

Please sign in to comment.