title: proper place to use location api in android mvvm architecture
body: <p>I have a scenario, I want to show user current weather data for that I am getting his/her current lat/lng and reverse geocoding it to get the city name. Once I have the city name I will make a network call and show the weather data. Apart from this, there are many location operations I need to perform. </p>
  
  <p>So I have created a class named as <code>LocationUtils.kt</code>. I am following MVVM architecture and want to know which is the ideal layer to call the <code>LocationUtils</code> methods, is it the <code>view</code> layer or the <code>viewmodel</code> layer or the <code>data</code> layer. Since <code>FusedLocationProvider</code> needs <code>context</code> and if I use it in <code>ViewModel</code> it will leak. So how to solve this problem?</p>
  
  <p><code>LocationUtils.kt</code>:</p>
  
  <pre><code>class LocationUtils {
    private lateinit var fusedLocationClient: FusedLocationProviderClient
  
    private fun isLocationEnabled(weakContext: Context?): Boolean {
      return when {
        Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.P -&gt; {
          // This is new method provided in API 28
          val locationManager = weakContext?.getSystemService(Context.LOCATION_SERVICE) as LocationManager
          locationManager.isLocationEnabled
        }
        Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.KITKAT -&gt; {
          // 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 -&gt; {
          val locationProviders = Settings.Secure.getString(weakContext?.contentResolver, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
          return !TextUtils.isEmpty(locationProviders)
        }
      }
    }
  
    @SuppressLint("MissingPermission")
    fun getCurrentLocation(
      weakContext: WeakReference&lt;Context&gt;,
      success: (String?) -&gt; Unit,
      error: () -&gt; Unit
    ) {
      if (isLocationEnabled(weakContext.get())) {
        weakContext.get()
            ?.let { context -&gt;
              fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
              fusedLocationClient.lastLocation.addOnSuccessListener { location -&gt;
                getCurrentCity(context, location, success)
              }
            }
      } else {
        error()
      }
    }
  
    private fun getCurrentCity(
      context: Context,
      location: Location?,
      success: (String?) -&gt; 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)
    }
  }
  </code></pre>