navigation: search near the phone, so "navigate to Del Taco" finds the closest one

This commit is contained in:
Seb3thehacker committed 2026-10-12 16:21:13 -07:00
1 parent 8069f54d8f
commit e76e9ddcf7
2 files changed
+34 -3

No files matched your search

@@ -301,11 +301,14 @@ class CarAppConnection(private val context: Context) {
/** /**
* "navigate to X" deep link, the same one Android Auto's own Assistant integration sends - * "navigate to X" deep link, the same one Android Auto's own Assistant integration sends -
* [ACTION_NAVIGATE] with the destination as a `geo:` search query, rather than anything * [ACTION_NAVIGATE] with the destination as a `geo:` search query, rather than anything
* app-specific. * app-specific. Centred on the phone when there's a fix: `geo:0,0` made Organic Maps pick the
* first Del Taco it found anywhere, not the nearest. The location goes only to the map app.
*/ */
private fun navigateIntent(destination: String) = private fun navigateIntent(destination: String): Intent {
Intent(CarContext.ACTION_NAVIGATE, Uri.parse("geo:0,0?q=" + Uri.encode(destination))) val near = app.seb3thehacker.gearslip.notify.CarMotion.nearHere(context) ?: "0,0"
return Intent(CarContext.ACTION_NAVIGATE, Uri.parse("geo:$near?q=" + Uri.encode(destination)))
.setComponent(component) .setComponent(component)
}
/** /**
* Sends a fresh destination to an app that's already running, instead of tearing it down * Sends a fresh destination to an app that's already running, instead of tearing it down
@@ -22,6 +22,33 @@ object CarMotion {
private var listener: LocationListener? = null private var listener: LocationListener? = null
private var speed = 0f private var speed = 0f
private var fixAt = 0L private var fixAt = 0L
@Volatile private var last: Location? = null
/** A fix older than this is somewhere the car has left. */
private const val NEAR_STALE_MS = 10 * 60_000L
/**
* Where the phone is, as "lat,lng", for "navigate to Del Taco" to find the nearest one. From
* this drive's GPS, or Android's last known fix; null with no permission or nothing recent.
*/
fun nearHere(context: Context): String? {
val fix = last?.takeIf { SystemClock.elapsedRealtime() - fixAt < NEAR_STALE_MS }
?: lastKnown(context)
?: return null
return String.format(java.util.Locale.US, "%.5f,%.5f", fix.latitude, fix.longitude)
}
private fun lastKnown(context: Context): Location? {
if (context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
context.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
) return null
val manager = context.getSystemService(LocationManager::class.java) ?: return null
val now = System.currentTimeMillis()
return manager.getProviders(true)
.mapNotNull { runCatching { manager.getLastKnownLocation(it) }.getOrNull() }
.filter { now - it.time < NEAR_STALE_MS }
.maxByOrNull { it.time }
}
val moving: Boolean val moving: Boolean
get() = SystemClock.elapsedRealtime() - fixAt < STALE_MS && speed > MOVING_MS get() = SystemClock.elapsedRealtime() - fixAt < STALE_MS && speed > MOVING_MS
@@ -34,6 +61,7 @@ object CarMotion {
override fun onLocationChanged(location: Location) { override fun onLocationChanged(location: Location) {
speed = if (location.hasSpeed()) location.speed else 0f speed = if (location.hasSpeed()) location.speed else 0f
fixAt = SystemClock.elapsedRealtime() fixAt = SystemClock.elapsedRealtime()
last = location
} }
} }
listener = l listener = l