diff --git a/.changes/geolocation-non-gms.md b/.changes/geolocation-non-gms.md new file mode 100644 index 0000000000..08cb181a12 --- /dev/null +++ b/.changes/geolocation-non-gms.md @@ -0,0 +1,5 @@ +--- +"geolocation": "minor" +--- + +Add support for the geolocation plugin on non-GMS android devices. diff --git a/examples/api/src-tauri/capabilities/mobile.json b/examples/api/src-tauri/capabilities/mobile.json index da77f5e53c..7c9927e834 100644 --- a/examples/api/src-tauri/capabilities/mobile.json +++ b/examples/api/src-tauri/capabilities/mobile.json @@ -16,6 +16,7 @@ "geolocation:allow-request-permissions", "geolocation:allow-watch-position", "geolocation:allow-get-current-position", + "geolocation:allow-clear-watch", "haptics:allow-impact-feedback", "haptics:allow-notification-feedback", "haptics:allow-selection-feedback", diff --git a/examples/api/src-tauri/gen/android/gradle/wrapper/gradle-wrapper.properties b/examples/api/src-tauri/gen/android/gradle/wrapper/gradle-wrapper.properties index 0df10d556c..fe17162822 100644 --- a/examples/api/src-tauri/gen/android/gradle/wrapper/gradle-wrapper.properties +++ b/examples/api/src-tauri/gen/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Tue May 10 19:22:52 CST 2022 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/examples/api/src/views/Geolocation.svelte b/examples/api/src/views/Geolocation.svelte index cd181dfbe2..7ce25c4133 100644 --- a/examples/api/src/views/Geolocation.svelte +++ b/examples/api/src/views/Geolocation.svelte @@ -2,11 +2,18 @@ import { checkPermissions, requestPermissions, - getCurrentPosition + getCurrentPosition, + + watchPosition, + clearWatch + } from '@tauri-apps/plugin-geolocation' export let onMessage + let pos = null + let watchId = null + async function getPosition() { let permissions = await checkPermissions() if ( @@ -17,13 +24,66 @@ } if (permissions.location === 'granted') { - getCurrentPosition().then(onMessage).catch(onMessage) + getCurrentPosition().then((position) => { + pos = position + onMessage(position) + }).catch((err) => { + pos = null + onMessage(err) + }) + } else { + onMessage('permission denied') + } + } + + async function watchPos() { + let permissions = await checkPermissions() + if ( + permissions.location === 'prompt' || + permissions.location === 'prompt-with-rationale' + ) { + permissions = await requestPermissions(['location']) + } + + if (permissions.location === 'granted') { + watchId = await watchPosition({ + enableHighAccuracy: true, + timeout: 5000, + maximumAge: 0 + }, (position) => { + pos = position + onMessage(position) + }) + onMessage('watchId: ' + watchId) } else { onMessage('permission denied') } } + + async function stopWatching() { + await clearWatch(watchId) + watchId = null + pos = null + } + + + + + + +{#if watchId} + Watch ID: {watchId} +{/if} + +{#if pos} +
{JSON.stringify(pos, null, 2)}
+{/if}
diff --git a/plugins/geolocation/android/src/main/java/Geolocation.kt b/plugins/geolocation/android/src/main/java/Geolocation.kt
index f93d230718..7d05c24d92 100644
--- a/plugins/geolocation/android/src/main/java/Geolocation.kt
+++ b/plugins/geolocation/android/src/main/java/Geolocation.kt
@@ -15,16 +15,18 @@ 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.LocationRequest as GmsLocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.Priority
+import android.location.LocationRequest
+import android.location.LocationListener
public class Geolocation(private val context: Context) {
private var fusedLocationClient: FusedLocationProviderClient? = null
- private var locationCallback: LocationCallback? = null
-
+ private var locationCallback: LocationCallback? = null // For gms
+ private var locationListener: LocationListener? = null // For android
fun isLocationServicesEnabled(): Boolean {
val lm = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
@@ -64,7 +66,27 @@ public class Geolocation(private val context: Context) {
errorCallback("Location disabled.")
}
} else {
- errorCallback("Google Play Services unavailable.")
+ val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
+ val provider = locationManager.getProviderProperties(LocationManager.GPS_PROVIDER)
+ if (provider == null) {
+ errorCallback("Location unavailable.")
+ return
+ }
+ if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
+ errorCallback("Location disabled.")
+ return
+ }
+ val req = LocationRequest.Builder(1_000L)
+ .setQuality(LocationRequest.QUALITY_HIGH_ACCURACY)
+ .setMaxUpdates(1)
+ .build()
+ locationManager.getCurrentLocation(LocationManager.GPS_PROVIDER, req, null, context.mainExecutor) { location ->
+ if (location == null) {
+ errorCallback("Location unavailable.")
+ } else {
+ successCallback(location)
+ }
+ }
}
}
@@ -89,7 +111,7 @@ public class Geolocation(private val context: Context) {
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)
+ val locationRequest = GmsLocationRequest.Builder(timeout)
.setMaxUpdateDelayMillis(timeout)
.setMinUpdateIntervalMillis(timeout)
.setPriority(prio)
@@ -112,7 +134,26 @@ public class Geolocation(private val context: Context) {
errorCallback("Location disabled.")
}
} else {
- errorCallback("Google Play Services not available.")
+ val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
+ val provider = locationManager.getProviderProperties(LocationManager.GPS_PROVIDER)
+ if (provider == null) {
+ errorCallback("Location unavailable.")
+ return
+ }
+ if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
+ errorCallback("Location disabled.")
+ return
+ }
+ val req = LocationRequest.Builder(timeout)
+ .setQuality(if (enableHighAccuracy) LocationRequest.QUALITY_HIGH_ACCURACY else LocationRequest.QUALITY_LOW_POWER)
+ .build()
+ val listener = object : android.location.LocationListener {
+ override fun onLocationChanged(location: android.location.Location) {
+ successCallback(location)
+ }
+ }
+ locationListener = listener
+ locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, req, context.mainExecutor, listener)
}
}
@@ -121,6 +162,11 @@ public class Geolocation(private val context: Context) {
fusedLocationClient?.removeLocationUpdates(locationCallback!!)
locationCallback = null
}
+ if (locationListener != null) {
+ val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
+ locationManager.removeUpdates(locationListener!!)
+ locationListener = null
+ }
}
@SuppressLint("MissingPermission")
diff --git a/plugins/geolocation/android/src/main/java/GeolocationPlugin.kt b/plugins/geolocation/android/src/main/java/GeolocationPlugin.kt
index cf81f5e3bc..ef36508e0b 100644
--- a/plugins/geolocation/android/src/main/java/GeolocationPlugin.kt
+++ b/plugins/geolocation/android/src/main/java/GeolocationPlugin.kt
@@ -136,6 +136,8 @@ class GeolocationPlugin(private val activity: Activity): Plugin(activity) {
{ error -> args.channel.sendObject(error) })
watchers[args.channel.id] = Pair(invoke, args)
+
+ invoke.resolve()
}
@Command