refactor: Move "provide location" preference to DataStore (#1877)

This commit is contained in:
James Rich 2025-05-19 16:23:29 -05:00 committed by GitHub
parent de49f6a48b
commit 38b9515fca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 83 additions and 37 deletions

View file

@ -22,9 +22,13 @@ import androidx.datastore.core.DataStore
import androidx.datastore.core.DataStoreFactory
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
import androidx.datastore.dataStoreFile
import androidx.datastore.preferences.core.PreferenceDataStoreFactory
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.preferencesDataStoreFile
import com.geeksville.mesh.AppOnlyProtos.ChannelSet
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
import com.geeksville.mesh.LocalOnlyProtos.LocalModuleConfig
import com.geeksville.mesh.repository.location.LOCATION_PREFERNCES_NAME
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -77,4 +81,11 @@ object DataStoreModule {
scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
)
}
@Singleton
@Provides
fun provideLocationPreferencesDataStore(@ApplicationContext appContext: Context): DataStore<Preferences> =
PreferenceDataStoreFactory.create(
produceFile = { appContext.preferencesDataStoreFile(LOCATION_PREFERNCES_NAME) }
)
}

View file

@ -27,14 +27,16 @@ import androidx.core.location.LocationListenerCompat
import androidx.core.location.LocationManagerCompat
import androidx.core.location.LocationRequestCompat
import androidx.core.location.altitude.AltitudeConverterCompat
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import com.geeksville.mesh.android.GeeksvilleApplication
import com.geeksville.mesh.android.Logging
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.asExecutor
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.map
import javax.inject.Inject
import javax.inject.Singleton
@ -42,13 +44,22 @@ import javax.inject.Singleton
class LocationRepository @Inject constructor(
private val context: Application,
private val locationManager: dagger.Lazy<LocationManager>,
private val locationPreferencesDataStore: DataStore<Preferences>,
) : Logging {
/**
* Status of whether the app is actively subscribed to location changes.
*/
private val _receivingLocationUpdates: MutableStateFlow<Boolean> = MutableStateFlow(false)
val receivingLocationUpdates: StateFlow<Boolean> get() = _receivingLocationUpdates
val locationPreferencesFlow = locationPreferencesDataStore.data.map {
it[PreferencesKeys.PROVIDE_LOCATION] == true
}
suspend fun updateLocationPreferences(provideLocation: Boolean) =
locationPreferencesDataStore.updateData { preferences ->
preferences.toMutablePreferences().apply {
set(PreferencesKeys.PROVIDE_LOCATION, provideLocation)
}
}
@RequiresPermission(anyOf = [ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION])
private fun LocationManager.requestLocationUpdates() = callbackFlow {
@ -84,7 +95,8 @@ class LocationRepository @Inject constructor(
}
info("Starting location updates with $providerList intervalMs=${intervalMs}ms and minDistanceM=${minDistanceM}m")
_receivingLocationUpdates.value = true
// _receivingLocationUpdates.value = true
updateLocationPreferences(true)
GeeksvilleApplication.analytics.track("location_start") // Figure out how many users needed to use the phone GPS
try {
@ -103,7 +115,7 @@ class LocationRepository @Inject constructor(
awaitClose {
info("Stopping location requests")
_receivingLocationUpdates.value = false
// _receivingLocationUpdates.value = false
GeeksvilleApplication.analytics.track("location_stop")
LocationManagerCompat.removeUpdates(this@requestLocationUpdates, locationListener)
@ -116,3 +128,9 @@ class LocationRepository @Inject constructor(
@RequiresPermission(anyOf = [ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION])
fun getLocations() = locationManager.get().requestLocationUpdates()
}
private object PreferencesKeys {
val PROVIDE_LOCATION = booleanPreferencesKey("provide_location")
}
const val LOCATION_PREFERNCES_NAME = "location_preferences"