Skip to content

Commit

Permalink
Migrate from Geocod API to Android's Geocoder class
Browse files Browse the repository at this point in the history
  • Loading branch information
abdurakhmonoff committed Mar 20, 2023
1 parent a37adc5 commit 9205525
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 139 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@ import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class RidezApplication : Application() {

}
class RidezApplication : Application()
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
package com.abdurakhmanov.ridez.data.repository

import com.abdurakhmanov.ridez.data.models.Location
import com.abdurakhmanov.ridez.data.response.CurrentAddress
import com.abdurakhmanov.ridez.data.source.local.LocationUpdate
import com.abdurakhmanov.ridez.data.source.local.LocationUpdateDao
import com.abdurakhmanov.ridez.data.source.remote.GeocoderApiService
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.*
import retrofit2.Response
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class LocationRepository @Inject constructor(
private val locationUpdateDao: LocationUpdateDao,
private val geocoderApiService: GeocoderApiService
private val locationUpdateDao: LocationUpdateDao
) {

@OptIn(ExperimentalCoroutinesApi::class)
Expand All @@ -31,8 +27,4 @@ class LocationRepository @Inject constructor(

suspend fun insertLocationUpdate(locationUpdate: LocationUpdate) =
locationUpdateDao.insert(locationUpdate)

suspend fun getAddress(apiKey: String, lat: Double, lon: Double?): Response<CurrentAddress?> {
return geocoderApiService.getAddress(apiKey, lat, lon)
}
}

This file was deleted.

This file was deleted.

32 changes: 0 additions & 32 deletions app/src/main/java/com/abdurakhmanov/ridez/di/NetworkModule.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.abdurakhmanov.ridez.di

import com.abdurakhmanov.ridez.data.repository.LocationRepository
import com.abdurakhmanov.ridez.data.source.local.LocationUpdateDao
import com.abdurakhmanov.ridez.data.source.remote.GeocoderApiService
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand All @@ -14,9 +13,8 @@ object RepositoryModule {

@Provides
fun provideLocationRepository(
locationUpdateDao: LocationUpdateDao,
geocoderApiService: GeocoderApiService
locationUpdateDao: LocationUpdateDao
): LocationRepository {
return LocationRepository(locationUpdateDao, geocoderApiService)
return LocationRepository(locationUpdateDao)
}
}
33 changes: 16 additions & 17 deletions app/src/main/java/com/abdurakhmanov/ridez/ui/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import android.annotation.SuppressLint
import android.content.Intent
import android.content.res.ColorStateList
import android.content.res.Configuration
import android.location.Address
import android.location.Geocoder
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import android.os.Bundle
Expand Down Expand Up @@ -37,8 +39,9 @@ import com.mapbox.maps.plugin.locationcomponent.*
import com.mapbox.maps.plugin.logo.logo
import com.mapbox.maps.plugin.scalebar.scalebar
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.delay
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.*

@AndroidEntryPoint
class MainActivity : AppCompatActivity(), OnRequestPermissionsResultCallback {
Expand Down Expand Up @@ -195,28 +198,24 @@ class MainActivity : AppCompatActivity(), OnRequestPermissionsResultCallback {
}

private fun showCurrentAddress() {
val geocoder = Geocoder(applicationContext, Locale("uz_UZ"))
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.liveLocation.collect { location ->
location?.let {
delay(5000)
viewModel.getCurrentAddress(
GEOCODER_API_KEY,
geocoder.getAddress(
location.latitude,
location.longitude
)
}
}
}
}
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.currentAddress.collect { currentAddress ->
if (currentAddress.isNotBlank()) {
binding.currentAddress.visibility = View.VISIBLE
binding.currentAddress.text = currentAddress
} else {
binding.currentAddress.visibility = View.INVISIBLE
) { address: Address? ->
lifecycleScope.launch(Dispatchers.Main) {
if (address != null) {
binding.currentAddress.visibility = View.VISIBLE
binding.currentAddress.text = address.getAddressLine(0)
} else {
binding.currentAddress.visibility = View.INVISIBLE
}
}
}
}
}
}
Expand Down
40 changes: 4 additions & 36 deletions app/src/main/java/com/abdurakhmanov/ridez/ui/MainViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import androidx.lifecycle.viewModelScope
import com.abdurakhmanov.ridez.data.repository.LocationRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject

Expand All @@ -14,46 +13,15 @@ class MainViewModel @Inject constructor(
private val locationRepository: LocationRepository
) : ViewModel() {

/**
* Set true if you want to start getting live location or false to stop
*/
private val _showLiveLocation = MutableStateFlow(true)
val showLiveLocation: StateFlow<Boolean>
get() = _showLiveLocation

/**
* Use this flow to get live location (updates constantly)
*/
val liveLocation = locationRepository.getLiveLocation(_showLiveLocation)

/**
* Geocoded address response
*/
private val _currentAddress = MutableStateFlow("")
val currentAddress: StateFlow<String>
get() = _currentAddress
private val showLiveLocation = MutableStateFlow(true)
val liveLocation = locationRepository.getLiveLocation(showLiveLocation)

init {
_showLiveLocation.value = true
showLiveLocation.value = true
}

/**
* Set the show argument to true if you want to start getting live location or false to stop
*/
fun showLiveLocation(show: Boolean) = viewModelScope.launch {
_showLiveLocation.value = show
showLiveLocation.value = show
}

/**
* Use this function to geocode location (latitude and longtitude)
*/
suspend fun getCurrentAddress(apiKey: String, latitude: Double, longitude: Double) {
val request = locationRepository.getAddress(apiKey, latitude, longitude)
if (request.isSuccessful) {
val requestBody = request.body()
if (requestBody != null && request.code() == 200) {
_currentAddress.value = requestBody.postaladdress
}
}
}
}
41 changes: 41 additions & 0 deletions app/src/main/java/com/abdurakhmanov/ridez/utils/LocationExt.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.abdurakhmanov.ridez.utils

import android.content.Context
import android.location.Geocoder
import android.location.LocationManager
import android.os.Build
import androidx.core.location.LocationManagerCompat

/**
* Checks whether user enabled the location or not.
*
* @return true if location is enabled or false if location is disabled
*/
fun Context.isLocationEnabled(): Boolean {
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
return LocationManagerCompat.isLocationEnabled(locationManager)
}

/**
* Gets current address of the user using latitude and longitude.
*
* @return user's current address
*/
@Suppress("DEPRECATION")
fun Geocoder.getAddress(
latitude: Double,
longitude: Double,
address: (android.location.Address?) -> Unit
) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
getFromLocation(latitude, longitude, 1) { address(it.firstOrNull()) }
return
}

try {
address(getFromLocation(latitude, longitude, 1)!!.firstOrNull())
} catch (e: Exception) {
address(null)
}
}
12 changes: 0 additions & 12 deletions app/src/main/java/com/abdurakhmanov/ridez/utils/PermissionExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.location.LocationManager
import android.net.Uri
import android.os.Build
import android.provider.Settings
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import androidx.core.location.LocationManagerCompat
import com.google.android.material.dialog.MaterialAlertDialogBuilder

/**
Expand Down Expand Up @@ -56,16 +54,6 @@ fun String.isPermissionGranted(
return false
}

/**
* Checks whether user enabled the location or not.
*
* @return true if location is enabled or false if location is disabled
*/
fun Context.isLocationEnabled(): Boolean {
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
return LocationManagerCompat.isLocationEnabled(locationManager)
}

/**
* Shows explanation dialog about location usage.
*/
Expand Down

0 comments on commit 9205525

Please sign in to comment.