У меня есть архитектура с ViewModel, которая управляет репозиторием, который сам запускает службу для получения обновлений местоположения.
Она построена как это :
Код: Выделить всё
class LocationViewModel @Inject constructor(val context: Context, private val locationRepository: LocationRepository): ViewModel() {
private val _locationUiState = MutableStateFlow(LocationUiState())
val locationUiState: StateFlow = _locationUiState.asStateFlow()
init {
viewModelScope.launch {
locationRepository.locationFlow.collect { location ->
_locationUiState.update { currentState ->
currentState.copy(location = location)
}
}
}
}
fun startLocationUpdates() {
locationRepository.startLocationUpdates()
}
}
Код: Выделить всё
class LocationRepository @Inject constructor(@ApplicationContext val context: Context) {
// MutableSharedFlow to emit location updates
private val _locationFlow = MutableStateFlow(Location("")) // replay = 1 to hold the last emitted value
val locationFlow : StateFlow = _locationFlow
// Function to update location in the repository
fun updateLocation(location: Location) {
_locationFlow.value = location
}
fun startLocationUpdates() {
val serviceIntent = Intent(context, LocationService::class.java)
ContextCompat.startForegroundService(context, serviceIntent)
}
Код: Выделить всё
@AndroidEntryPoint
class LocationService(): Service() {
@Inject lateinit var locationRepository: LocationRepository
private lateinit var powerManager: PowerManager
private lateinit var wakeLock: PowerManager.WakeLock
private lateinit var fusedLocationClient: FusedLocationProviderClient
private val locationRequest = LocationRequest
.Builder(Priority.PRIORITY_HIGH_ACCURACY, 1000)
.setMinUpdateIntervalMillis(1000)
.build()
private var _locationData = MutableStateFlow(Location(""))
val locationData: StateFlow = _locationData.asStateFlow()
override fun onCreate() {
super.onCreate()
powerManager = getSystemService(POWER_SERVICE) as PowerManager
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp::LocationWakeLock")
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
createNotificationChannel()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
wakeLock.acquire()
startForeground(FOREGROUND_SERVICE_TYPE_LOCATION, getNotification())
val locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
locationResult.lastLocation?.let { location ->
locationRepository.updateLocation(location)
}
}
}
fusedLocationClient.requestLocationUpdates(locationRequest,
locationCallback,
Looper.getMainLooper())
return START_STICKY
}
Я пробовал много разных подходов к StateFlow или LiveData, но ни один из них не сработал.
Я начинаю думать, что это может быть проблема с сопрограммами и потоками, в которых что-то происходит, но я я новичок в Kotlin и Jetpack, поэтому не уверен в этом
Подробнее здесь: https://stackoverflow.com/questions/791 ... e-to-my-ui