首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >android mvvm架构中使用location api的合适位置

android mvvm架构中使用location api的合适位置
EN

Stack Overflow用户
提问于 2019-08-11 09:48:30
回答 2查看 1.5K关注 0票数 6

我有一个场景,我想向用户显示我正在获取他/她当前的lat/lng的当前天气数据,并对其进行反向地理编码以获得城市名称。一旦我有了城市名称,我将进行网络呼叫并显示天气数据。除此之外,我还需要执行许多定位操作。

所以我创建了一个名为LocationUtils.kt的类。我正在遵循MVVM架构,我想知道哪个层是调用LocationUtils方法的理想层,是view层、viewmodel层还是data层。因为FusedLocationProvider需要context,如果我在ViewModel中使用它,它会泄漏。那么如何解决这个问题呢?

LocationUtils.kt

代码语言:javascript
运行
AI代码解释
复制
class LocationUtils {
  private lateinit var fusedLocationClient: FusedLocationProviderClient

  private fun isLocationEnabled(weakContext: Context?): Boolean {
    return when {
      Build.VERSION.SDK_INT >= Build.VERSION_CODES.P -> {
        // This is new method provided in API 28
        val locationManager = weakContext?.getSystemService(Context.LOCATION_SERVICE) as LocationManager
        locationManager.isLocationEnabled
      }
      Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT -> {
        // This is Deprecated in API 28
        val mode = Settings.Secure.getInt(
            weakContext?.contentResolver, Settings.Secure.LOCATION_MODE,
            Settings.Secure.LOCATION_MODE_OFF
        )
        mode != Settings.Secure.LOCATION_MODE_OFF

      }
      else -> {
        val locationProviders = Settings.Secure.getString(weakContext?.contentResolver, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
        return !TextUtils.isEmpty(locationProviders)
      }
    }
  }

  @SuppressLint("MissingPermission")
  fun getCurrentLocation(
    weakContext: WeakReference<Context>,
    success: (String?) -> Unit,
    error: () -> Unit
  ) {
    if (isLocationEnabled(weakContext.get())) {
      weakContext.get()
          ?.let { context ->
            fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
            fusedLocationClient.lastLocation.addOnSuccessListener { location ->
              getCurrentCity(context, location, success)
            }
          }
    } else {
      error()
    }
  }

  private fun getCurrentCity(
    context: Context,
    location: Location?,
    success: (String?) -> Unit
  ) {
    val city = try {
      location?.let {
        val geocoder = Geocoder(context, Locale.getDefault())
        val address = geocoder.getFromLocation(it.latitude, it.longitude, 1)
        address[0].locality
      }
    } catch (e: Exception) {
      "Bangalore"
    }
    success(city)
  }
}
EN

回答 2

Stack Overflow用户

发布于 2019-08-29 05:37:18

我也在解决同样的问题。我还必须处理使用MVVM架构向用户显示天气数据的问题。此时此刻,我被困在你现在所处的同一点。解决方案似乎是所谓的“依赖注入(DI)”。基本上,我们可以使用'Dagger 2‘这样的工具/框架将Context等依赖项注入到我们的ViewModel中。DI比直接将Context传递给ViewModel具有更低的耦合性,并导致更好的顺应性。所以,在实现DI之后,FusedLocationProvider的实际位置将在ViewModel中。也许其他人可以更好地阐述我的解释。一旦我自己实现了依赖注入,我就会更新我的答案。

票数 2
EN

Stack Overflow用户

发布于 2020-02-20 17:51:04

我把它放到我的ViewModel里了。为了将context作为参数传递给ViewModel,您可以扩展AndroidViewModel而不是ViewModel。示例:

代码语言:javascript
运行
AI代码解释
复制
class CurrentViewModel(application: Application) : AndroidViewModel(application) {
    val context = application
    val locationResolver = LocationResolver(context)//this one converts latitude and longitude into City name of type String


fun detectCity() {
        Log.d(LocationResolver.TAG, "entered detectLocation()")
        val fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
        fusedLocationClient.lastLocation
            .addOnSuccessListener { location ->
                if (location != null) {
                    Repository._currentName.value = locationResolver.getLocationFromCoordinates(
                        location.latitude,
                        location.longitude
                    )
                    Log.d(
                        LocationResolver.TAG,
                        "New city name is:" + Repository.currentLocationCity
                    )
                }

            }
    }

然后,您可以通过DataBinding观察输出。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57448952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档