mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-05-03 12:15:11 +02:00
145 lines
6.0 KiB
Kotlin
145 lines
6.0 KiB
Kotlin
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package app.tauri.geolocation
|
|
|
|
import android.annotation.SuppressLint
|
|
import android.content.Context
|
|
import android.location.Location
|
|
import android.location.LocationManager
|
|
import android.os.SystemClock
|
|
import androidx.core.location.LocationManagerCompat
|
|
import app.tauri.Logger
|
|
import com.google.android.gms.common.ConnectionResult
|
|
import com.google.android.gms.common.GoogleApiAvailability
|
|
import com.google.android.gms.location.FusedLocationProviderClient
|
|
import com.google.android.gms.location.LocationCallback
|
|
import com.google.android.gms.location.LocationRequest
|
|
import com.google.android.gms.location.LocationResult
|
|
import com.google.android.gms.location.LocationServices
|
|
import com.google.android.gms.location.Priority
|
|
|
|
|
|
public class Geolocation(private val context: Context) {
|
|
private var fusedLocationClient: FusedLocationProviderClient? = null
|
|
private var locationCallback: LocationCallback? = null
|
|
|
|
|
|
fun isLocationServicesEnabled(): Boolean {
|
|
val lm = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
|
return LocationManagerCompat.isLocationEnabled(lm)
|
|
}
|
|
|
|
@SuppressWarnings("MissingPermission")
|
|
fun sendLocation(enableHighAccuracy: Boolean, successCallback: (location: Location) -> Unit, errorCallback: (error: String) -> Unit) {
|
|
val resultCode = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context);
|
|
if (resultCode == ConnectionResult.SUCCESS) {
|
|
val lm = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
|
|
|
if (this.isLocationServicesEnabled()) {
|
|
var networkEnabled = false
|
|
|
|
try {
|
|
networkEnabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
|
|
} catch (_: Exception) {
|
|
Logger.error("isProviderEnabled failed")
|
|
}
|
|
|
|
val lowPrio = if (networkEnabled) Priority.PRIORITY_BALANCED_POWER_ACCURACY else Priority.PRIORITY_LOW_POWER
|
|
val prio = if (enableHighAccuracy) Priority.PRIORITY_HIGH_ACCURACY else lowPrio
|
|
|
|
LocationServices
|
|
.getFusedLocationProviderClient(context)
|
|
.getCurrentLocation(prio, null)
|
|
.addOnFailureListener { e -> e.message?.let { errorCallback(it) } }
|
|
.addOnSuccessListener { location ->
|
|
if (location == null) {
|
|
errorCallback("Location unavailable.")
|
|
} else {
|
|
successCallback(location)
|
|
}
|
|
}
|
|
} else {
|
|
errorCallback("Location disabled.")
|
|
}
|
|
} else {
|
|
errorCallback("Google Play Services unavailable.")
|
|
}
|
|
}
|
|
|
|
@SuppressLint("MissingPermission")
|
|
fun requestLocationUpdates(enableHighAccuracy: Boolean, timeout: Long, successCallback: (location: Location) -> Unit, errorCallback: (error: String) -> Unit) {
|
|
val resultCode = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context);
|
|
if (resultCode == ConnectionResult.SUCCESS) {
|
|
clearLocationUpdates()
|
|
fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
|
|
|
|
val lm = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
|
|
|
if (this.isLocationServicesEnabled()) {
|
|
var networkEnabled = false
|
|
|
|
try {
|
|
networkEnabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
|
|
} catch (_: Exception) {
|
|
Logger.error("isProviderEnabled failed")
|
|
}
|
|
|
|
val lowPrio = if (networkEnabled) Priority.PRIORITY_BALANCED_POWER_ACCURACY else Priority.PRIORITY_LOW_POWER
|
|
val prio = if (enableHighAccuracy) Priority.PRIORITY_HIGH_ACCURACY else lowPrio
|
|
|
|
val locationRequest = LocationRequest.Builder(timeout)
|
|
.setMaxUpdateDelayMillis(timeout)
|
|
.setMinUpdateIntervalMillis(timeout)
|
|
.setPriority(prio)
|
|
.build()
|
|
|
|
locationCallback =
|
|
object : LocationCallback() {
|
|
override fun onLocationResult(locationResult: LocationResult) {
|
|
val lastLocation = locationResult.lastLocation
|
|
if (lastLocation == null) {
|
|
errorCallback("Location unavailable.")
|
|
} else {
|
|
successCallback(lastLocation)
|
|
}
|
|
}
|
|
}
|
|
|
|
fusedLocationClient?.requestLocationUpdates(locationRequest, locationCallback!!, null)
|
|
} else {
|
|
errorCallback("Location disabled.")
|
|
}
|
|
} else {
|
|
errorCallback("Google Play Services not available.")
|
|
}
|
|
}
|
|
|
|
fun clearLocationUpdates() {
|
|
if (locationCallback != null) {
|
|
fusedLocationClient?.removeLocationUpdates(locationCallback!!)
|
|
locationCallback = null
|
|
}
|
|
}
|
|
|
|
@SuppressLint("MissingPermission")
|
|
fun getLastLocation(maximumAge: Long): Location? {
|
|
var lastLoc: Location? = null
|
|
val lm = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
|
|
|
for (provider in lm.allProviders) {
|
|
val tmpLoc = lm.getLastKnownLocation(provider)
|
|
if (tmpLoc != null) {
|
|
val locationAge = SystemClock.elapsedRealtimeNanos() - tmpLoc.elapsedRealtimeNanos
|
|
val maxAgeNano = maximumAge * 1000000L
|
|
if (locationAge <= maxAgeNano && (lastLoc == null || lastLoc.elapsedRealtimeNanos > tmpLoc.elapsedRealtimeNanos)) {
|
|
lastLoc = tmpLoc
|
|
}
|
|
}
|
|
}
|
|
|
|
return lastLoc
|
|
}
|
|
}
|