0

我在做什么

我正在构建一个天气预报应用程序,该应用程序使用 fusedLocationProviderClient 获取设备位置并尝试根据该位置获取天气预报,我正在以现代方式执行此操作(即使用协程回调流)

这是我从 fusedLocationProviderClient 获取位置的代码

class LocationProviderUseCase(
    private val appContext: Context,
    private val client:FusedLocationProviderClient
    ) {
    companion object {
        private const val UPDATE_INTERVAL_SECS = 40L
        private const val FASTEST_UPDATE_INTERVAL_SECS = 15L
    }

    fun fetchUpdates():Flow<String> = callbackFlow {
        val locationRequest = LocationRequest.create().apply {
            interval = TimeUnit.SECONDS.toMillis(UPDATE_INTERVAL_SECS)
            fastestInterval = TimeUnit.SECONDS.toMillis(FASTEST_UPDATE_INTERVAL_SECS)
            priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        }
        val callBack = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult) {
                super.onLocationResult(locationResult)
                val location = locationResult.lastLocation
                val userLocation = MapLocation(
                    latitude = location.latitude,
                    longitude = location.longitude,
                    bearing = location.bearing
                )
                try {
                    this@callbackFlow.trySend(getDeviceCityName(userLocation)).isSuccess
                }catch (e:Exception){
                    Log.d("(TAG)","error in fetching the location ${e.message.toString()}")
                }

            }
        }

        client.requestLocationUpdates(
            locationRequest,
            callBack,
            Looper.getMainLooper()
        ).addOnFailureListener {e->
            close(e)
        }
        awaitClose {
            client.removeLocationUpdates(callBack)
        }
        close()
    }

    private fun getDeviceCityName(location:MapLocation):String{
        val geocoder = Geocoder(appContext, Locale.getDefault())
        val addresses: List<Address> = geocoder.getFromLocation(
            location.latitude,
            location.longitude,
            5)
        val cityName: String = addresses[0].locality
        Log.d("(Saquib)","the city name is "+cityName)
        return cityName
    }
}

这是我的 ViewModel 代码

class HomeFramentViewModel(
    private val useCase: LocationProviderUseCase,
    private val repo: WeatherRepository): ViewModel() {
    private val location = MutableLiveData<String>()
    val weatherData = location.switchMap {city->
        Log.d("(TAG)","the location is changed and switch_map is triggered")    //Never printed
        liveData (Dispatchers.IO){
            emit(repo.getWeatherOfCity(city))
        }
    }

    fun getWeatherOfCity(){
        Log.d("(Saquib)","the getWeatherOfCity method is getting called successfully")
        viewModelScope.launch {
            useCase.fetchUpdates().collectLatest {city->
                Log.d("(TAG)","the name of the city from the flow is $city")      //Successfully  printed
                location.postValue(city)
            }
        }
    }
}

我的问题是什么

其中getWeatherOfCity(city)是一个暂停功能,所以因为我是 Coroutines 的新手,尤其是流程,所以我不确定我是否以正确的方式执行它(即执行location.postValue(city)是否正确),所以如果这不是正确的做法,那么正确的方法是什么,如果是,那么我的代码中的错误是什么

请帮我解决这个问题,在此先感谢:)

4

0 回答 0