Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework permission setup #259

Merged
merged 11 commits into from
Dec 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ android {
applicationId "org.blitzortung.android.app"
minSdkVersion 21
targetSdkVersion 34
versionCode 323
versionCode 325
versionName '2.2.6'
multiDexEnabled false
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />

<application
android:name=".BOApplication"
Expand Down
34 changes: 34 additions & 0 deletions app/src/main/java/org/blitzortung/android/app/AppService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,23 @@

package org.blitzortung.android.app

import android.annotation.TargetApi
import android.app.AlarmManager
import android.app.Notification
import android.app.PendingIntent
import android.app.Service
import android.content.ComponentName
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.core.app.ServiceCompat
import dagger.android.AndroidInjection
import org.blitzortung.android.alert.handler.AlertHandler
import org.blitzortung.android.app.controller.NotificationHandler.Companion.CHANNEL_ID
import org.blitzortung.android.app.view.OnSharedPreferenceChangeListener
import org.blitzortung.android.app.view.PreferenceKey
import org.blitzortung.android.app.view.get
Expand Down Expand Up @@ -127,9 +132,36 @@ class AppService : Service(), OnSharedPreferenceChangeListener {
Log.d(Main.LOG_TAG, "AppService.onStartCommand() non matching intent ${intent?.action}")
}

val intent = Intent(this, Main::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
val flags = PendingIntent.FLAG_CANCEL_CURRENT or (if (isAtLeast(Build.VERSION_CODES.M)) {
PendingIntent.FLAG_IMMUTABLE
} else {
0
})
val contentIntent = PendingIntent.getActivity(this, 0, intent, flags)

if (isAtLeast(26)) {
startForground(contentIntent)
}

return START_STICKY
}

@TargetApi(Build.VERSION_CODES.O)
private fun startForground(contentIntent: PendingIntent?) {
val notification = Notification.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.icon)
.setContentTitle(this.resources.getText(R.string.app_name))
.setContentText("bla")
.setContentIntent(contentIntent)
.setAutoCancel(true)
.setWhen(System.currentTimeMillis())
.setShowWhen(true).build()

ServiceCompat.startForeground(this, 0, notification, FOREGROUND_SERVICE_TYPE_MANIFEST)
}

override fun onBind(intent: Intent): IBinder? {
Log.i(Main.LOG_TAG, "AppService.onBind() $intent")

Expand All @@ -139,6 +171,8 @@ class AppService : Service(), OnSharedPreferenceChangeListener {
override fun onDestroy() {
super.onDestroy()

ServiceCompat.stopForeground(this, 0)

preferences.unregisterOnSharedPreferenceChangeListener(this)
isEnabled = false

Expand Down
85 changes: 48 additions & 37 deletions app/src/main/java/org/blitzortung/android/app/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.graphics.Color
import android.location.LocationManager.*
Expand Down Expand Up @@ -421,20 +420,6 @@ class Main : FragmentActivity(), OnSharedPreferenceChangeListener {
mapView.controller.animateTo(GeoPoint(latitude, longitude), targetZoomLevel, OwnMapView.DEFAULT_ZOOM_SPEED)
}

val isDebugBuild: Boolean
get() {
var dbg = false
try {
val pm = packageManager
val pi = pm.getPackageInfo(packageName, 0)

dbg = ((pi.applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE) != 0)
} catch (ignored: Exception) {
}

return dbg
}

override fun onStart() {
super.onStart()
Log.d(LOG_TAG, "Main.onStart()")
Expand Down Expand Up @@ -638,47 +623,73 @@ class Main : FragmentActivity(), OnSharedPreferenceChangeListener {
}

val checkSelfPermission = checkSelfPermission(permission)
Log.v(LOG_TAG, "self permission: $checkSelfPermission")
val requiresPermission = checkSelfPermission != PackageManager.PERMISSION_GRANTED
Log.v(
LOG_TAG,
"Main.requestLocationPermissions() self permission: $checkSelfPermission, required: $requiresPermission"
)

val requestCode = (LocationProviderRelation.byProviderName[locationProviderName]?.ordinal ?: Int.MAX_VALUE)
if (requiresPermission) {
val locationText = resources.getString(R.string.location_permission_background_disclosure)
AlertDialog.Builder(this).setMessage(locationText).setCancelable(false)
.setNeutralButton(android.R.string.ok) { dialog, count ->
requestPermission(
arrayOf(permission), requestCode, R.string.location_permission_required
)
}.show()
requestPermission(
permission, requestCode,
R.string.location_permission_required
)
} else {
if (requiresBackgroundPermission) {
requestPermission(
arrayOf(ACCESS_BACKGROUND_LOCATION),
requestCode,
R.string.location_permission_background_required
)
if (requiresBackgroundPermission && isAtLeast(Build.VERSION_CODES.Q)) {
val locationText = this.resources.getString(R.string.location_permission_background_disclosure)
AlertDialog.Builder(this).setMessage(locationText).setCancelable(false)
.setPositiveButton(android.R.string.ok) { dialog, count ->
requestPermission(
ACCESS_BACKGROUND_LOCATION,
requestCode,
R.string.location_permission_background_required
)
}.show()
}
}
}
}


@TargetApi(Build.VERSION_CODES.M)
private fun requestPermission(permission: Array<String>, requestCode: Int, permissionRequiredStringId: Int) {
val shouldShowPermissionRationale = shouldShowRequestPermissionRationale(permission[0])
val permissionStatus = checkSelfPermission(permission[0])
private fun requestPermission(permission: String, requestCode: Int, permissionRequiredStringId: Int) {
val shouldShowPermissionRationale = shouldShowRequestPermissionRationale(permission)
val permissionIsGranted = checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED
Log.v(
LOG_TAG,
"Main.requestPermission() permission: ${permission.joinToString()}, status: $permissionStatus, shouldRequest: ${!shouldShowPermissionRationale}"
"Main.requestPermission() permission: $permission, isGranted: $permissionIsGranted, shouldShowRationale: ${!shouldShowPermissionRationale}"
)
if (!shouldShowPermissionRationale && permissionStatus != PackageManager.PERMISSION_GRANTED) {
requestPermissions(permission, requestCode)
} else {

if (!permissionIsGranted) {
if (shouldShowPermissionRationale) {
Toast.makeText(baseContext, permissionRequiredStringId, Toast.LENGTH_LONG).show()
requestPermissionsAfterDialog(permissionRequiredStringId, permission, requestCode)
} else {
requestPermissions(arrayOf(permission), requestCode)
}
}
}

@TargetApi(Build.VERSION_CODES.M)
private fun requestPermissionsAfterDialog(
dialogTextResource: Int,
permission: String,
requestCode: Int,
) {
Log.v(
LOG_TAG,
"Main.requestPermissionsAfterDialog() permission: $permission, dialogResource: $dialogTextResource, requestCode: $requestCode"
)

val locationText = resources.getString(dialogTextResource)
AlertDialog.Builder(this).setMessage(locationText).setCancelable(false)
.setPositiveButton(android.R.string.ok) { dialog, count ->
Log.v(LOG_TAG, "Main.requestPermissionsAfterDialog() clicked OK, before request")
requestPermissions(arrayOf(permission), requestCode)
Log.v(LOG_TAG, "Main.requestPermissionsAfterDialog() clicked OK, after request")
}.show()
}

@TargetApi(Build.VERSION_CODES.M)
private fun requestWakeupPermissions(context: Context) {
Log.v(LOG_TAG, "requestWakeupPermissions() background alerts: $backgroundAlertEnabled")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class QuickSettingsDialog : DialogFragment() {
val selectedRegion = getSelectedIndex(regionValues, currentRegionValue)

val gridSizeValues = resources.getStringArray(R.array.grid_size_values)
val currentGridSizeValue = preferences.get(PreferenceKey.GRID_SIZE, gridSizeValues[1])
val currentGridSizeValue = preferences.get(PreferenceKey.GRID_SIZE, gridSizeValues[0])
val selectedGridSize = getSelectedIndex(gridSizeValues, currentGridSizeValue)

val countThresholdValues = resources.getStringArray(R.array.count_threshold_values)
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ Ivan Karev ([email protected])\nTschechisch: Jakub Mareček (jakubmarecek715@
<string name="location_permission_required">Für die Ortsbestimmung über den Gerätestandort ist die Berechtigung erforderlich.</string>
<string name="location_permission_background_required">Für die Ortsbestimmung über den Gerätestandort im Hintergrund ist die Berechtigung erforderlich.</string>
<string name="changelog">Änderungsprotokoll</string>
<string name="location_permission_background_disclosure">Diese App verwendet Standortdaten, auch wenn die App geschlossen ist oder nicht verwendet wird, wenn Warnungen im Hintergrund mit einer Gerätestandortquelle verwendet werden.</string>
<string name="location_permission_background_disclosure">Diese App verwendet Standortdaten und Datenübertragung, auch wenn die App geschlossen ist oder nicht verwendet wird, <b>sofern Warnungen im Hintergrund aktiviert wurden</b>.</string>
<string name="menu">Menü öffnen</string>
<string name="slider_current">jetzt</string>
<string name="slider_past">Vergangenheit</string>
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ Traducción ruso por: Ivan Karev ([email protected])\n
<string name="changelog">Change log</string>
<string name="location_permission_required">Se requiere permiso de ubicación cuando se usa una fuente de ubicación de dispositivo.</string>
<string name="location_permission_background_required">Se requiere permiso de ubicación en segundo plano cuando se utiliza una fuente de ubicación de dispositivo.</string>
<string name="location_permission_background_disclosure">Esta aplicación usa datos de ubicación incluso cuando la aplicación está cerrada o no está en uso cuando se usan alarmas en segundo plano con una fuente de ubicación del dispositivo.</string>
<string name="location_permission_background_disclosure">Esta aplicación utiliza datos de ubicación y datos de red incluso cuando la aplicación está cerrada o no está en uso cuando usa alarmas en segundo plano con una fuente de ubicación del dispositivo.</string>
<string name="menu">Menú abierto</string>
<string name="slider_current">ahora</string>
<string name="slider_past">Pasado</string>
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ Russe: Ivan Karev ([email protected])\n
<string name="changelog">Change log</string>
<string name="location_permission_required">L\'autorisation de localisation est requise lors de l\'utilisation d\'une source de localisation de périphérique.</string>
<string name="location_permission_background_required">L\'autorisation de localisation en arrière-plan est requise lors de l\'utilisation d\'une source de localisation de périphérique.</string>
<string name="location_permission_background_disclosure">Cette application utilise les données de localisation même lorsque l\'application est fermée ou non utilisée lors de l\'utilisation d\'alarmes d\'arrière-plan avec une source de localisation de périphérique.</string>
<string name="location_permission_background_disclosure">Cette application utilise les données de localisation et les données réseau même lorsque l\'application est fermée ou n\'est pas utilisée lors de l\'utilisation d\'alarmes en arrière-plan avec une source de localisation d\'appareil.</string>
<string name="slider_current">maintenant</string>
<string name="slider_past">Passé</string>
<string name="slider_legend">[Heures]</string>
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values-it/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,6 @@ Traduzione russo di: Ivan Karev ([email protected])\n
<string name="changelog">Change log</string>
<string name="location_permission_required">L\'autorizzazione alla posizione è richiesta quando si utilizza un\'origine della posizione del dispositivo.</string>
<string name="location_permission_background_required">L\'autorizzazione alla posizione in background è necessaria quando si utilizza un\'origine della posizione del dispositivo.</string>
<string name="location_permission_background_disclosure">Questa app utilizza i dati sulla posizione anche quando l\'app è chiusa o non è in uso quando si utilizzano allarmi in background con un\'origine della posizione del dispositivo.</string>
<string name="location_permission_background_disclosure">Questa app utilizza i dati sulla posizione e i dati di rete anche quando l\'app è chiusa o non in uso quando si utilizzano allarmi in background con una fonte di posizione del dispositivo.</string>
<string name="animation_interval_duration">Intervallo di animazione</string>
</resources>
2 changes: 1 addition & 1 deletion app/src/main/res/values-nl/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ Russisch: Ivan Karev ([email protected])\n
<string name="location_permission_required">Locatie delen is nodig om je huidige locatie te bepalen.</string>
<string name="changelog">Change log</string>
<string name="location_permission_background_required">Achtergrondlocatietoestemming is vereist bij het gebruik van een apparaatlocatiebron.</string>
<string name="location_permission_background_disclosure">Deze app gebruikt locatiegegevens, zelfs wanneer de app is gesloten of niet in gebruik is, wanneer achtergrondalarmen worden gebruikt met een apparaatlocatiebron.</string>
<string name="location_permission_background_disclosure">Deze app gebruikt locatiegegevens en netwerkgegevens, zelfs wanneer de app gesloten is of niet in gebruik is bij gebruik van achtergrondalarmen met een apparaatlocatiebron.</string>
<string name="menu">Menu openen</string>
<string name="slider_current">nu</string>
<string name="slider_past">Verleden</string>
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values-pl/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ rosyjski: Ivan Karev ([email protected])\n
<string name="map_scale_summary">Wybierz skalowanie [%] kafelków mapy</string>
<string name="location_permission_required">W przypadku korzystania ze źródła lokalizacji urządzenia wymagane jest uprawnienie do lokalizacji.</string>
<string name="location_permission_background_required">W przypadku korzystania ze źródła lokalizacji urządzenia wymagane jest uprawnienie do lokalizacji w tle.</string>
<string name="location_permission_background_disclosure">Ta aplikacja korzysta z danych o lokalizacji nawet wtedy, gdy jest zamknięta lub nieużywana, podczas korzystania z alarmów w tle.</string>
<string name="location_permission_background_disclosure">Ta aplikacja korzysta z danych o Twojej lokalizacji i danych sieciowych, nawet jeśli jest zamknięta lub nieużywana, a w tle włączone są alarmy.</string>
<string name="osmdroid_storage_warning">Nie można znaleźć miejsca do zapisu mapy. Proszę zgłosić.</string>
<string name="changelog">Dziennik zmian</string>
<string name="menu">Otwórz menu</string>
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ Russian by Ivan Karev ([email protected])\n
<string name="map_scale_summary">Select scaling [%] of map tiles</string>
<string name="location_permission_required">Location permission is required when using a device location source.</string>
<string name="location_permission_background_required">Background location permission is required when using a device location source.</string>
<string name="location_permission_background_disclosure">This app uses location data even when the app is closed or not in use when using background alarms with a device location source.</string>
<string name="location_permission_background_disclosure">This app uses location data and network data transfer even when the app is closed or not in use when using background alarms.</string>
<string name="osmdroid_storage_warning">Cannot find writable storage for map. Please report.</string>
<string name="changelog">Change log</string>
<string name="menu">Open menu</string>
Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '8.7.1' apply false
id 'com.android.library' version '8.7.1' apply false
id 'com.android.application' version '8.7.3' apply false
id 'com.android.library' version '8.7.3' apply false
id 'org.jetbrains.kotlin.android' version '2.0.20' apply false
id "org.sonarqube" version "5.1.0.4882"
}
Expand Down
Loading