Created
December 9, 2019 08:05
-
-
Save mvasilova/7f4604dc6cc3b293dfa9a7b26fff4de5 to your computer and use it in GitHub Desktop.
Definition of geolocation - latitude, longitude (with GPS, ipAddress, RxPermissions) - Android (Kotlin)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Definition of geolocation - latitude, longitude in Fragment | |
private lateinit var fusedLocationClient: FusedLocationProviderClient | |
private lateinit var locationRequest: LocationRequest | |
private lateinit var locationCallback: LocationCallback | |
private lateinit var rxPermissions: RxPermissions | |
private var latitude: Double? = 0.0 | |
private var longitude: Double? = 0.0 | |
val compositeDisposable = CompositeDisposable() | |
companion object { | |
private const val UPDATE_INTERVAL: Long = 15 * 1000 | |
private const val FASTEST_INTERVAL: Long = 5000 | |
} | |
override fun onCreate(savedInstanceState: Bundle?) { | |
fusedLocationClient = LocationServices.getFusedLocationProviderClient(activity!!) | |
rxPermissions = RxPermissions(this) | |
locationCallback = LocationCallback() | |
super.onCreate(savedInstanceState) | |
} | |
//Call this method on ClickListener | |
private fun checkPermission() { | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | |
compositeDisposable.add(rxPermissions | |
.request( | |
Manifest.permission.ACCESS_FINE_LOCATION, | |
Manifest.permission.ACCESS_COARSE_LOCATION | |
) | |
.subscribe { granted -> | |
if (!granted) { | |
Toast.makeText( | |
activity, | |
getString(R.string.toast_location_permission), | |
Toast.LENGTH_LONG | |
).show() | |
} else { | |
checkEnabledGPS() | |
} | |
}) | |
} else { | |
checkEnabledGPS() | |
} | |
} | |
private fun checkEnabledGPS() { | |
val service: LocationManager = activity?.getSystemService(Context.LOCATION_SERVICE) as LocationManager | |
val isEnabled = | |
service.isProviderEnabled(LocationManager.GPS_PROVIDER) || service.isProviderEnabled( | |
LocationManager.NETWORK_PROVIDER) | |
if (!isEnabled) { | |
Toast.makeText(activity, getString(R.string.toast_location_enabled), Toast.LENGTH_LONG).show() | |
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS) | |
startActivity(intent) | |
} else { | |
startLocationUpdates() | |
} | |
} | |
private fun startLocationUpdates() { | |
locationRequest = LocationRequest.create() | |
locationRequest.run { | |
priority = LocationRequest.PRIORITY_LOW_POWER | |
interval = UPDATE_INTERVAL | |
setFastestInterval(FASTEST_INTERVAL) | |
} | |
val builder = LocationSettingsRequest.Builder() | |
builder.addLocationRequest(locationRequest) | |
val locationSettingsRequest = builder.build() | |
val settingsClient = LocationServices.getSettingsClient(activity!!) | |
settingsClient!!.checkLocationSettings(locationSettingsRequest) | |
registerLocationListener() | |
} | |
private fun registerLocationListener() { | |
locationCallback = object : LocationCallback() { | |
override fun onLocationResult(locationResult: LocationResult?) { | |
locationResult?.let { | |
obtainLocalization() | |
fusedLocationClient.removeLocationUpdates(this) | |
} | |
} | |
} | |
LocationServices.getFusedLocationProviderClient(activity!!) | |
.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper()) | |
} | |
private fun obtainLocalization() { | |
fusedLocationClient.lastLocation | |
.addOnSuccessListener { location: Location? -> | |
location?.let { | |
latitude = location.latitude | |
longitude = location.longitude | |
//TODO | |
//Use latitude & longitude forward | |
} | |
} | |
} | |
override fun onDestroy() { | |
super.onDestroy() | |
fusedLocationClient.removeLocationUpdates(locationCallback) | |
compositeDisposable.clear() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.Manifest | |
import android.app.Activity | |
import android.content.Context | |
import android.location.Location | |
import android.location.LocationManager | |
import android.os.Build | |
import android.os.Looper | |
import androidx.fragment.app.Fragment | |
import com.google.android.gms.location.* | |
import com.tbruyelle.rxpermissions2.RxPermissions | |
import io.reactivex.disposables.CompositeDisposable | |
import ru.profsoft.farmakopeika.ui.utils.getLocalIpAddress | |
class LocationManager(val activity: Activity?, val fragment: Fragment) { | |
private lateinit var locationRequest: LocationRequest | |
private var fusedLocationClient: FusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(activity!!) | |
private var locationCallback: LocationCallback = LocationCallback() | |
private var rxPermissions: RxPermissions = RxPermissions(fragment) | |
private var latitude: Double = 0.0 | |
private var longitude: Double = 0.0 | |
private var ipAddress: String = "" | |
private val compositeDisposable = CompositeDisposable() | |
companion object { | |
private const val UPDATE_INTERVAL: Long = 15 * 1000 | |
private const val FASTEST_INTERVAL: Long = 5000 | |
} | |
fun getLocation(listener: (LocationData) -> Unit) { | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | |
compositeDisposable.add(rxPermissions | |
.request( | |
Manifest.permission.ACCESS_FINE_LOCATION, | |
Manifest.permission.ACCESS_COARSE_LOCATION | |
) | |
.subscribe { granted -> | |
if (!granted) { | |
//Use IP instead GPS when permissions not granted | |
ipAddress = getLocalIpAddress() | |
listener.invoke(LocationData(ipAddress, null)) | |
} else { | |
checkEnabledGPS(listener) | |
} | |
}) | |
} else { | |
checkEnabledGPS(listener) | |
} | |
} | |
private fun checkEnabledGPS(listener: (LocationData) -> Unit) { | |
val service: LocationManager = | |
activity?.getSystemService(Context.LOCATION_SERVICE) as LocationManager | |
val isEnabled = service.isProviderEnabled(LocationManager.GPS_PROVIDER) || service.isProviderEnabled(LocationManager.NETWORK_PROVIDER) | |
if (!isEnabled) { | |
ipAddress = getLocalIpAddress() | |
listener.invoke(LocationData(ipAddress, null)) | |
} else { | |
locationRequest = LocationRequest.create() | |
locationRequest.run { | |
priority = LocationRequest.PRIORITY_LOW_POWER | |
interval = UPDATE_INTERVAL | |
setFastestInterval(FASTEST_INTERVAL) | |
} | |
val builder = LocationSettingsRequest.Builder() | |
builder.addLocationRequest(locationRequest) | |
val locationSettingsRequest = builder.build() | |
val settingsClient = LocationServices.getSettingsClient(activity) | |
settingsClient!!.checkLocationSettings(locationSettingsRequest) | |
locationCallback = object : LocationCallback() { | |
override fun onLocationResult(locationResult: LocationResult?) { | |
locationResult?.let { | |
fusedLocationClient.lastLocation | |
.addOnSuccessListener { location: Location? -> | |
location?.let { | |
latitude = location.latitude | |
longitude = location.longitude | |
listener.invoke(LocationData(null, Pair(latitude, longitude))) | |
} | |
} | |
fusedLocationClient.removeLocationUpdates(this) | |
} | |
} | |
} | |
LocationServices.getFusedLocationProviderClient(activity).requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper()) | |
} | |
} | |
fun clearAll() { | |
fusedLocationClient.removeLocationUpdates(locationCallback) | |
compositeDisposable.clear() | |
} | |
data class LocationData(var ipAddress: String?, var coordinates: Pair<Double, Double>?) | |
} | |
//Usages in Activity or Fragment | |
lateinit var locationManager: LocationManager | |
//onCreate method | |
locationManager = LocationManager(activity, this) | |
//actions for clicklistener or sometheng else | |
locationManager.getLocation { | |
if (it.ipAddress != null && it.ipAddress != "") { | |
//TODO | |
//use ipAddress | |
//Example: | |
//presenter.getLocationByIp(it.ipAddress!!) | |
} else if (it.coordinates != null) { | |
//TODO | |
//use ipAddress | |
//Example: | |
//presenter.getLocationByCoordinates(it.coordinates!!.first, it.coordinates!!.second) | |
} else { | |
//TODO | |
//if ip == null && coordinates == null | |
} | |
} | |
//Extensions | |
fun getLocalIpAddress(): String { | |
try { | |
val en = NetworkInterface.getNetworkInterfaces() | |
while (en.hasMoreElements()) { | |
val intf = en.nextElement() | |
val enumIpAddr = intf.inetAddresses | |
while (enumIpAddr.hasMoreElements()) { | |
val inetAddress = enumIpAddr.nextElement() | |
if (!inetAddress.isLoopbackAddress && inetAddress is Inet4Address) { | |
return inetAddress.getHostAddress() | |
} | |
} | |
} | |
} catch (ex: SocketException) { | |
ex.printStackTrace() | |
} | |
return "" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment