diff options
Diffstat (limited to 'android-app/app/src/main/kotlin/com/example')
| -rw-r--r-- | android-app/app/src/main/kotlin/com/example/androidapp/ui/LocationPermissionHandler.kt | 43 | ||||
| -rw-r--r-- | android-app/app/src/main/kotlin/com/example/androidapp/ui/MainActivity.kt | 33 |
2 files changed, 65 insertions, 11 deletions
diff --git a/android-app/app/src/main/kotlin/com/example/androidapp/ui/LocationPermissionHandler.kt b/android-app/app/src/main/kotlin/com/example/androidapp/ui/LocationPermissionHandler.kt new file mode 100644 index 0000000..664d5bb --- /dev/null +++ b/android-app/app/src/main/kotlin/com/example/androidapp/ui/LocationPermissionHandler.kt @@ -0,0 +1,43 @@ +package com.example.androidapp.ui + +/** + * Encapsulates location permission decision logic. + * + * Extracted for testability — no direct Android framework dependency in the core logic. + * + * Permissions handled: ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION + * + * Usage: + * - Call [start] on activity start to check existing permission or trigger a request. + * - Call [onResult] from the ActivityResultLauncher callback with the permission grants map. + */ +class LocationPermissionHandler( + /** Returns true if location permission is already granted. */ + private val checkGranted: () -> Boolean, + /** Called when location permission is available (already granted or just granted). */ + private val onGranted: () -> Unit, + /** Called when location permission is denied or the user refuses (including "never ask again"). */ + private val onDenied: () -> Unit, + /** Called when permission needs to be requested from the user via the system dialog. */ + private val requestPermissions: () -> Unit +) { + /** + * Check current permission state and dispatch: + * - If already granted, invoke [onGranted] immediately. + * - Otherwise, invoke [requestPermissions] to trigger the system dialog. + */ + fun start() { + if (checkGranted()) onGranted() else requestPermissions() + } + + /** + * Process the result from the system permission dialog. + * + * @param grants Map of permission name → granted status from ActivityResultLauncher. + * Invokes [onGranted] if any permission was granted, [onDenied] otherwise. + * An empty map (e.g. "never ask again" scenario) also triggers [onDenied]. + */ + fun onResult(grants: Map<String, Boolean>) { + if (grants.values.any { it }) onGranted() else onDenied() + } +} diff --git a/android-app/app/src/main/kotlin/com/example/androidapp/ui/MainActivity.kt b/android-app/app/src/main/kotlin/com/example/androidapp/ui/MainActivity.kt index 0a326f4..17a636f 100644 --- a/android-app/app/src/main/kotlin/com/example/androidapp/ui/MainActivity.kt +++ b/android-app/app/src/main/kotlin/com/example/androidapp/ui/MainActivity.kt @@ -24,11 +24,30 @@ class MainActivity : AppCompatActivity() { private val defaultLat = 37.8 private val defaultLon = -122.4 + private val permissionHandler: LocationPermissionHandler by lazy { + LocationPermissionHandler( + checkGranted = { + ContextCompat.checkSelfPermission( + this, Manifest.permission.ACCESS_FINE_LOCATION + ) == PackageManager.PERMISSION_GRANTED + }, + onGranted = { fetchLocationAndLoad() }, + onDenied = { loadWeatherAtDefault() }, + requestPermissions = { + locationPermissionLauncher.launch( + arrayOf( + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION + ) + ) + } + ) + } + private val locationPermissionLauncher = registerForActivityResult( ActivityResultContracts.RequestMultiplePermissions() ) { grants -> - val granted = grants.values.any { it } - if (granted) fetchLocationAndLoad() else loadWeatherAtDefault() + permissionHandler.onResult(grants) } override fun onCreate(savedInstanceState: Bundle?) { @@ -72,15 +91,7 @@ class MainActivity : AppCompatActivity() { } private fun requestLocationOrLoad() { - val fine = Manifest.permission.ACCESS_FINE_LOCATION - val coarse = Manifest.permission.ACCESS_COARSE_LOCATION - val hasPermission = ContextCompat.checkSelfPermission(this, fine) == - PackageManager.PERMISSION_GRANTED - if (hasPermission) { - fetchLocationAndLoad() - } else { - locationPermissionLauncher.launch(arrayOf(fine, coarse)) - } + permissionHandler.start() } private fun fetchLocationAndLoad() { |
