From 4405faa90792304414d0701bcbf0956992419ebd Mon Sep 17 00:00:00 2001 From: darken Date: Wed, 5 Jan 2022 12:14:34 +0100 Subject: [PATCH] Handle permissions on < Android 12 --- app/src/main/AndroidManifest.xml | 7 +++---- .../darken/capod/common/permissions/Permission.kt | 15 +++++++++++---- .../capod/main/ui/overview/OverviewFragmentVM.kt | 15 +++++++++++---- .../main/ui/overview/cards/PermissionCardVH.kt | 9 +++++++-- app/src/main/res/values/strings.xml | 2 ++ 5 files changed, 34 insertions(+), 14 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e2c72da2..d88de417 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -21,8 +21,7 @@ - - + + android:label="@string/app_name" + android:launchMode="singleTop"> diff --git a/app/src/main/java/eu/darken/capod/common/permissions/Permission.kt b/app/src/main/java/eu/darken/capod/common/permissions/Permission.kt index ee75bc3f..251a3b29 100644 --- a/app/src/main/java/eu/darken/capod/common/permissions/Permission.kt +++ b/app/src/main/java/eu/darken/capod/common/permissions/Permission.kt @@ -35,15 +35,22 @@ enum class Permission( permissionId = "android.permission.BLUETOOTH_SCAN", ), ACCESS_FINE_LOCATION( - minApiLevel = Build.VERSION_CODES.S, + minApiLevel = Build.VERSION_CODES.BASE, maxApiLevel = Build.VERSION_CODES.R, labelRes = R.string.permission_access_fine_location_label, descriptionRes = R.string.permission_access_fine_location_description, permissionId = "android.permission.ACCESS_FINE_LOCATION", + ), + ACCESS_BACKGROUND_LOCATION( + minApiLevel = Build.VERSION_CODES.Q, + maxApiLevel = Build.VERSION_CODES.R, + labelRes = R.string.permission_background_location_label, + descriptionRes = R.string.permission_background_location_description, + permissionId = "android.permission.ACCESS_BACKGROUND_LOCATION", ) } -fun Permission.isGrantedOrNotRequired(context: Context): Boolean = when { - !withinApiLevel(minApiLevel, maxApiLevel) -> true - else -> ContextCompat.checkSelfPermission(context, permissionId) == PackageManager.PERMISSION_GRANTED +fun Permission.isRequired(context: Context): Boolean = when { + !withinApiLevel(minApiLevel, maxApiLevel) -> false + else -> ContextCompat.checkSelfPermission(context, permissionId) != PackageManager.PERMISSION_GRANTED } \ No newline at end of file diff --git a/app/src/main/java/eu/darken/capod/main/ui/overview/OverviewFragmentVM.kt b/app/src/main/java/eu/darken/capod/main/ui/overview/OverviewFragmentVM.kt index 9e00078b..424a02fe 100644 --- a/app/src/main/java/eu/darken/capod/main/ui/overview/OverviewFragmentVM.kt +++ b/app/src/main/java/eu/darken/capod/main/ui/overview/OverviewFragmentVM.kt @@ -7,13 +7,15 @@ import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext import eu.darken.capod.common.coroutine.DispatcherProvider import eu.darken.capod.common.debug.autoreport.DebugSettings +import eu.darken.capod.common.debug.logging.log import eu.darken.capod.common.debug.recording.core.RecorderModule import eu.darken.capod.common.livedata.SingleLiveEvent import eu.darken.capod.common.navigation.navVia import eu.darken.capod.common.permissions.Permission -import eu.darken.capod.common.permissions.isGrantedOrNotRequired +import eu.darken.capod.common.permissions.isRequired import eu.darken.capod.common.uix.ViewModel3 import eu.darken.capod.main.core.GeneralSettings +import eu.darken.capod.main.core.MonitorMode import eu.darken.capod.main.ui.overview.cards.PermissionCardVH import eu.darken.capod.main.ui.overview.cards.pods.BasicSingleApplePodsCardVH import eu.darken.capod.main.ui.overview.cards.pods.DualApplePodsCardVH @@ -54,10 +56,12 @@ class OverviewFragmentVM @Inject constructor( private val permissionCheckTrigger = MutableStateFlow(UUID.randomUUID()) private val requiredPermissions: Flow> = permissionCheckTrigger .map { - Permission.values().filter { !it.isGrantedOrNotRequired(context) } + Permission.values().filter { it.isRequired(context) } } .onEach { - if (it.isEmpty()) { + log(TAG) { "Missing permissions: $it" } + if (it.isEmpty() && generalSettings.monitorMode.value != MonitorMode.MANUAL) { + log(TAG) { "All permissions granted, starting monitor." } monitorControl.startMonitor() } } @@ -84,6 +88,7 @@ class OverviewFragmentVM @Inject constructor( } } } + .catch { errorEvents.postValue(it) } val listItems: LiveData> = combine( updateTicker, @@ -114,7 +119,9 @@ class OverviewFragmentVM @Inject constructor( .run { items.addAll(this) } items - }.asLiveData2() + } + .catch { errorEvents.postValue(it) } + .asLiveData2() fun onPermissionResult(granted: Boolean) { if (granted) permissionCheckTrigger.value = UUID.randomUUID() diff --git a/app/src/main/java/eu/darken/capod/main/ui/overview/cards/PermissionCardVH.kt b/app/src/main/java/eu/darken/capod/main/ui/overview/cards/PermissionCardVH.kt index 21b179ff..a2b292d1 100644 --- a/app/src/main/java/eu/darken/capod/main/ui/overview/cards/PermissionCardVH.kt +++ b/app/src/main/java/eu/darken/capod/main/ui/overview/cards/PermissionCardVH.kt @@ -2,6 +2,8 @@ package eu.darken.capod.main.ui.overview.cards import android.view.ViewGroup import eu.darken.capod.R +import eu.darken.capod.common.lists.binding +import eu.darken.capod.common.lists.differ.DifferItem import eu.darken.capod.common.permissions.Permission import eu.darken.capod.databinding.MainPermissionItemBinding import eu.darken.capod.main.ui.overview.OverviewAdapter @@ -19,7 +21,7 @@ class PermissionCardVH(parent: ViewGroup) : override val onBindData: MainPermissionItemBinding.( item: Item, payloads: List - ) -> Unit = { item, _ -> + ) -> Unit = binding(payload = true) { item -> permissionLabel.setText(item.permission.labelRes) permissionDescription.setText(item.permission.descriptionRes) grantAction.setOnClickListener { item.onRequest(item.permission) } @@ -29,6 +31,9 @@ class PermissionCardVH(parent: ViewGroup) : val permission: Permission, val onRequest: (Permission) -> Unit ) : OverviewAdapter.Item { - override val stableId: Long = this.javaClass.hashCode().toLong() + override val stableId: Long = permission.hashCode().toLong() + + override val payloadProvider: ((DifferItem, DifferItem) -> DifferItem?) + get() = { old, new -> if (new::class.isInstance(old)) new else null } } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8d089751..80ff9549 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -101,4 +101,6 @@ Start music playback music when wearing the device (if supported). L %1$s | C %2$s | R %3$s Headphones: %1$s + ACCESS_BACKGROUND_LOCATION + Allows an app to access location in the background. \ No newline at end of file