Åpne valgt tilfluktsrom i ekstern kartapp for gangvei
Ny knapp (ic_directions) ved siden av del-knappen i bunnarket. Fyrer ACTION_VIEW med geo:lat,lon?q=lat,lon(Tilfluktsrom – adresse), som håndteres av enhver installert kartapp — inkludert offline-kapable OsmAnd/Organic Maps, viktig ved degradert nett. Ingen vendor-URL-er. - Koordinater formateres med Locale.US så norsk systemspråk ikke gir desimalkomma i URI-en - Fallback: ActivityNotFoundException → koordinater kopieres til klippebordet + Toast (navigate_no_map_app). startActivity+catch brukes framfor resolveActivity() for å slippe <queries> (pakkesynlighet API 30+) - Strenger action_navigate / navigate_no_map_app i en/nb/nn - 48dp berøringsflate og contentDescription som de andre ikonknappene Verifisert på emulator (Pixel 6 API 35): trykk → START ACTION_VIEW geo: → Google Maps åpnes. Forgejo: #2 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FrDGDmN2WAXvNPS85rWJGK
This commit is contained in:
parent
2a0c9b49ce
commit
daf8b62d39
7 changed files with 84 additions and 2 deletions
|
|
@ -1,6 +1,9 @@
|
|||
package no.naiv.tilfluktsrom
|
||||
|
||||
import android.Manifest
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.view.HapticFeedbackConstants
|
||||
|
|
@ -22,6 +25,7 @@ import android.provider.Settings
|
|||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.TimeUnit
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
|
|
@ -271,6 +275,11 @@ class MainActivity : AppCompatActivity(), SensorEventListener {
|
|||
shareShelter()
|
||||
}
|
||||
|
||||
binding.navigateButton.setOnClickListener {
|
||||
it.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
|
||||
openInMapApp()
|
||||
}
|
||||
|
||||
binding.cacheRetryButton.setOnClickListener {
|
||||
it.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
|
||||
val loc = currentLocation
|
||||
|
|
@ -816,6 +825,51 @@ class MainActivity : AppCompatActivity(), SensorEventListener {
|
|||
startActivity(Intent.createChooser(shareIntent, getString(R.string.action_share)))
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the selected shelter in an external map app for walking directions.
|
||||
*
|
||||
* Uses a plain geo: URI (ACTION_VIEW), never a vendor-specific URL, so any
|
||||
* installed map app can claim it — including offline-capable ones such as
|
||||
* OsmAnd and Organic Maps, which matters when the network is degraded.
|
||||
* geo:lat,lon?q=lat,lon(label) is the de-facto form all major apps parse.
|
||||
*
|
||||
* Coordinates are formatted with Locale.US: a Norwegian default locale
|
||||
* would otherwise emit decimal commas and produce an unparsable URI.
|
||||
*
|
||||
* If no app handles geo: (rare, but possible on de-Googled devices with
|
||||
* no map app installed), the coordinates are copied to the clipboard and
|
||||
* a toast says so, so the user can still paste them somewhere useful.
|
||||
* startActivity + ActivityNotFoundException is used instead of
|
||||
* resolveActivity() because the latter is subject to package-visibility
|
||||
* filtering on API 30+ and would need a <queries> manifest entry.
|
||||
*/
|
||||
private fun openInMapApp() {
|
||||
val selected = selectedShelter
|
||||
if (selected == null) {
|
||||
Toast.makeText(this, R.string.share_no_shelter, Toast.LENGTH_SHORT).show()
|
||||
return
|
||||
}
|
||||
|
||||
val shelter = selected.shelter
|
||||
val lat = String.format(Locale.US, "%.6f", shelter.latitude)
|
||||
val lon = String.format(Locale.US, "%.6f", shelter.longitude)
|
||||
val label = Uri.encode("${getString(R.string.app_name)} \u2013 ${shelter.adresse}")
|
||||
val geoUri = Uri.parse("geo:$lat,$lon?q=$lat,$lon($label)")
|
||||
|
||||
try {
|
||||
startActivity(Intent(Intent.ACTION_VIEW, geoUri))
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
val coords = "$lat, $lon"
|
||||
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
clipboard.setPrimaryClip(ClipData.newPlainText(getString(R.string.app_name), coords))
|
||||
Toast.makeText(
|
||||
this,
|
||||
getString(R.string.navigate_no_map_app, coords),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
/** Update the freshness indicator below the status bar with color-coded age. */
|
||||
private fun updateFreshnessIndicator() {
|
||||
val lastUpdate = repository.getLastUpdateMs()
|
||||
|
|
|
|||
12
app/src/main/res/drawable/ic_directions.xml
Normal file
12
app/src/main/res/drawable/ic_directions.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Material Design "directions" icon (Apache 2.0) — opens the selected
|
||||
shelter in an external map app for walking directions. -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M21.71,11.29l-9,-9c-0.39,-0.39 -1.02,-0.39 -1.41,0l-9,9c-0.39,0.39 -0.39,1.02 0,1.41l9,9c0.39,0.39 1.02,0.39 1.41,0l9,-9c0.39,-0.38 0.39,-1.01 0,-1.41zM14,14.5L14,12h-4v3L8,15v-4c0,-0.55 0.45,-1 1,-1h5L14,7.5l3.5,3.5 -3.5,3.5z" />
|
||||
</vector>
|
||||
|
|
@ -265,6 +265,16 @@
|
|||
tools:text="1.2 km - 400 plasser - Rom 776" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/navigateButton"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:contentDescription="@string/action_navigate"
|
||||
android:src="@drawable/ic_directions"
|
||||
app:tint="@color/text_secondary" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/shareButton"
|
||||
android:layout_width="48dp"
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
<string name="action_cache_ok">Lagre kart</string>
|
||||
<string name="action_cache_now">Lagre nå</string>
|
||||
<string name="action_reset_navigation">Tilbakestill navigasjonsvisning</string>
|
||||
<string name="action_navigate">Åpne i kartapp</string>
|
||||
<string name="action_share">Del tilfluktsrom</string>
|
||||
<string name="action_grant_permission">Gi tilgang</string>
|
||||
<string name="action_location_settings">Aktiver</string>
|
||||
|
|
@ -58,6 +59,7 @@
|
|||
<string name="share_subject">Tilfluktsrom</string>
|
||||
<string name="share_body">Tilfluktsrom: %1$s\n%2$d plasser\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f\n%5$s</string>
|
||||
<string name="share_no_shelter">Ingen tilfluktsrom valgt</string>
|
||||
<string name="navigate_no_map_app">Fant ingen kartapp – koordinater kopiert: %1$s</string>
|
||||
|
||||
<!-- Tilgjengelighet -->
|
||||
<string name="direction_arrow_description">Retning til tilfluktsrom, %s unna</string>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
<string name="action_cache_ok">Lagre kart</string>
|
||||
<string name="action_cache_now">Lagre no</string>
|
||||
<string name="action_reset_navigation">Tilbakestill navigasjonsvising</string>
|
||||
<string name="action_navigate">Opne i kartapp</string>
|
||||
<string name="action_share">Del tilfluktsrom</string>
|
||||
<string name="action_grant_permission">Gje tilgang</string>
|
||||
<string name="action_location_settings">Aktiver</string>
|
||||
|
|
@ -58,6 +59,7 @@
|
|||
<string name="share_subject">Tilfluktsrom</string>
|
||||
<string name="share_body">Tilfluktsrom: %1$s\n%2$d plassar\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f\n%5$s</string>
|
||||
<string name="share_no_shelter">Ingen tilfluktsrom valt</string>
|
||||
<string name="navigate_no_map_app">Fann ingen kartapp – koordinatar kopierte: %1$s</string>
|
||||
|
||||
<!-- Tilgjenge -->
|
||||
<string name="direction_arrow_description">Retning til tilfluktsrom, %s unna</string>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
<string name="action_cache_ok">Cache map</string>
|
||||
<string name="action_cache_now">Cache now</string>
|
||||
<string name="action_reset_navigation">Reset navigation view</string>
|
||||
<string name="action_navigate">Open in map app</string>
|
||||
<string name="action_share">Share shelter</string>
|
||||
<string name="action_grant_permission">Grant access</string>
|
||||
<string name="action_location_settings">Enable</string>
|
||||
|
|
@ -58,6 +59,7 @@
|
|||
<string name="share_subject">Emergency shelter</string>
|
||||
<string name="share_body">Shelter: %1$s\n%2$d places\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f\n%5$s</string>
|
||||
<string name="share_no_shelter">No shelter selected</string>
|
||||
<string name="navigate_no_map_app">No map app found – coordinates copied: %1$s</string>
|
||||
|
||||
<!-- Accessibility -->
|
||||
<string name="direction_arrow_description">Direction to shelter, %s away</string>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue