diff --git a/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt b/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt
index b7c98a9..71cf891 100644
--- a/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt
+++ b/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt
@@ -10,9 +10,11 @@ import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.location.Location
+import android.location.LocationManager
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.Uri
+import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.util.Log
@@ -95,27 +97,9 @@ class MainActivity : AppCompatActivity(), SensorEventListener {
if (fineGranted || coarseGranted) {
startLocationUpdates()
} else {
- // Check if user permanently denied (don't show rationale = permanently denied)
- val shouldShowRationale = ActivityCompat.shouldShowRequestPermissionRationale(
- this, Manifest.permission.ACCESS_FINE_LOCATION
- )
- if (!shouldShowRationale) {
- // Permission permanently denied — guide user to settings
- AlertDialog.Builder(this)
- .setTitle(R.string.permission_location_title)
- .setMessage(R.string.permission_denied)
- .setPositiveButton(android.R.string.ok) { _, _ ->
- val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
- data = Uri.fromParts("package", packageName, null)
- }
- startActivity(intent)
- }
- .setNegativeButton(android.R.string.cancel, null)
- .show()
- } else {
- Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_LONG).show()
- }
+ Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_LONG).show()
}
+ updateLocationStatusBanner()
}
override fun onCreate(savedInstanceState: Bundle?) {
@@ -259,6 +243,8 @@ class MainActivity : AppCompatActivity(), SensorEventListener {
}
private fun loadData() {
+ updateLocationStatusBanner()
+
lifecycleScope.launch {
try {
var hasData = repository.hasCachedData()
@@ -378,6 +364,44 @@ class MainActivity : AppCompatActivity(), SensorEventListener {
)
}
+ private fun updateLocationStatusBanner() {
+ val banner = binding.noLocationBanner
+ val text = binding.locationBannerText
+ val action = binding.locationBannerAction
+
+ when {
+ !locationProvider.hasLocationPermission() -> {
+ text.setText(R.string.status_location_permission_needed)
+ action.setText(R.string.action_grant_permission)
+ action.setOnClickListener {
+ startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
+ data = Uri.fromParts("package", packageName, null)
+ })
+ }
+ banner.visibility = View.VISIBLE
+ }
+ !isLocationServicesEnabled() -> {
+ text.setText(R.string.status_location_services_off)
+ action.setText(R.string.action_location_settings)
+ action.setOnClickListener {
+ startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))
+ }
+ banner.visibility = View.VISIBLE
+ }
+ else -> banner.visibility = View.GONE
+ }
+ }
+
+ private fun isLocationServicesEnabled(): Boolean {
+ val lm = getSystemService(Context.LOCATION_SERVICE) as? LocationManager ?: return false
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+ lm.isLocationEnabled
+ } else {
+ lm.isProviderEnabled(LocationManager.GPS_PROVIDER) ||
+ lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
+ }
+ }
+
private fun startLocationUpdates() {
// Use repeatOnLifecycle(STARTED) so GPS stops when Activity is paused
lifecycleScope.launch {
@@ -757,6 +781,10 @@ class MainActivity : AppCompatActivity(), SensorEventListener {
binding.mapView.onResume()
myLocationOverlay?.enableMyLocation()
+ // Re-check permission + location-services state so the banner updates
+ // when the user returns from Settings.
+ updateLocationStatusBanner()
+
val sm = sensorManager ?: return
// Try rotation vector first (best compass source)
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 2c43bcf..f00127b 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -76,7 +76,7 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:contentDescription="@string/a11y_map"
- app:layout_constraintTop_toBottomOf="@id/statusBar"
+ app:layout_constraintTop_toBottomOf="@id/noLocationBanner"
app:layout_constraintBottom_toTopOf="@id/bottomSheet" />
@@ -87,7 +87,7 @@
android:background="@color/compass_bg"
android:contentDescription="@string/a11y_compass"
android:visibility="gone"
- app:layout_constraintTop_toBottomOf="@id/statusBar"
+ app:layout_constraintTop_toBottomOf="@id/noLocationBanner"
app:layout_constraintBottom_toTopOf="@id/bottomSheet">
+
+
+
+
+
+
+
+
Lagre nå
Tilbakestill navigasjonsvisning
Del tilfluktsrom
+ Gi tilgang
+ Aktiver
Ingen frakoblet kart lagret. Kartet krever internett.
+ Posisjonstilgang nødvendig for å finne nærmeste tilfluktsrom. Du kan også trykke på et merke i kartet.
+ Stedstjenester er slått av. Aktiver dem eller velg et tilfluktsrom fra kartet.
Posisjonstillatelse kreves
diff --git a/app/src/main/res/values-nn/strings.xml b/app/src/main/res/values-nn/strings.xml
index 1bf2330..9c5414f 100644
--- a/app/src/main/res/values-nn/strings.xml
+++ b/app/src/main/res/values-nn/strings.xml
@@ -30,7 +30,11 @@
Lagre no
Tilbakestill navigasjonsvising
Del tilfluktsrom
+ Gje tilgang
+ Aktiver
Ingen fråkopla kart lagra. Kartet krev internett.
+ Posisjonstilgang trengst for å finne næraste tilfluktsrom. Du kan òg trykke på eit merke i kartet.
+ Stedstenester er slått av. Aktiver dei eller vel eit tilfluktsrom frå kartet.
Posisjonsløyve krevst
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 1eede01..d3de8e6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -30,7 +30,11 @@
Cache now
Reset navigation view
Share shelter
+ Grant access
+ Enable
No offline map cached. Map requires internet.
+ Location access needed to find the nearest shelter. You can also tap a marker on the map.
+ Location services are off. Enable them or pick a shelter from the map.
Location permission required