improve location permission check

pull/441/head
andrekir 2022-06-01 00:04:31 -03:00
rodzic 9b45ba84f7
commit 6184e9f30c
4 zmienionych plików z 41 dodań i 28 usunięć

Wyświetl plik

@ -189,7 +189,7 @@ class MainActivity : BaseActivity(), Logging,
/** Get the minimum permissions our app needs to run correctly /** Get the minimum permissions our app needs to run correctly
*/ */
private fun getMinimumPermissions(): List<String> { private fun getMinimumPermissions(): Array<String> {
val perms = mutableListOf( val perms = mutableListOf(
Manifest.permission.WAKE_LOCK Manifest.permission.WAKE_LOCK
@ -218,18 +218,12 @@ class MainActivity : BaseActivity(), Logging,
/** Ask the user to grant Bluetooth scan/discovery permission */ /** Ask the user to grant Bluetooth scan/discovery permission */
fun requestScanPermission() = requestPermission(getScanPermissions(), true) fun requestScanPermission() = requestPermission(getScanPermissions(), true)
/** Ask the user to grant foreground location permission */
fun requestLocationPermission() = requestPermission(getLocationPermissions())
/** Ask the user to grant background location permission */
fun requestBackgroundPermission() = requestPermission(getBackgroundPermissions())
/** /**
* @return a localized string warning user about missing permissions. Or null if everything is find * @return a localized string warning user about missing permissions. Or null if everything is find
*/ */
@SuppressLint("InlinedApi") @SuppressLint("InlinedApi")
fun getMissingMessage( fun getMissingMessage(
missingPerms: List<String> = getMinimumPermissions() missingPerms: Array<String> = getMinimumPermissions()
): String? { ): String? {
val renamedPermissions = mapOf( val renamedPermissions = mapOf(
// Older versions of android don't know about these permissions - ignore failure to grant // Older versions of android don't know about these permissions - ignore failure to grant
@ -262,7 +256,7 @@ class MainActivity : BaseActivity(), Logging,
* @return true if we already have the needed permissions * @return true if we already have the needed permissions
*/ */
private fun requestPermission( private fun requestPermission(
missingPerms: List<String> = getMinimumPermissions(), missingPerms: Array<String> = getMinimumPermissions(),
shouldShowDialog: Boolean = false shouldShowDialog: Boolean = false
): Boolean = ): Boolean =
if (missingPerms.isNotEmpty()) { if (missingPerms.isNotEmpty()) {
@ -275,7 +269,7 @@ class MainActivity : BaseActivity(), Logging,
// Ask for all the missing perms // Ask for all the missing perms
ActivityCompat.requestPermissions( ActivityCompat.requestPermissions(
this, this,
missingPerms.toTypedArray(), missingPerms,
DID_REQUEST_PERM DID_REQUEST_PERM
) )
} }

Wyświetl plik

@ -47,17 +47,17 @@ fun Context.hasGps(): Boolean =
/** /**
* return a list of the permissions we don't have * return a list of the permissions we don't have
*/ */
fun Context.getMissingPermissions(perms: List<String>) = perms.filter { fun Context.getMissingPermissions(perms: List<String>): Array<String> = perms.filter {
ContextCompat.checkSelfPermission( ContextCompat.checkSelfPermission(
this, this,
it it
) != PackageManager.PERMISSION_GRANTED ) != PackageManager.PERMISSION_GRANTED
} }.toTypedArray()
/** /**
* Bluetooth connect permissions (or empty if we already have what we need) * Bluetooth connect permissions (or empty if we already have what we need)
*/ */
fun Context.getConnectPermissions(): List<String> { fun Context.getConnectPermissions(): Array<String> {
val perms = mutableListOf<String>() val perms = mutableListOf<String>()
/* TODO - wait for targetSdkVersion 31 /* TODO - wait for targetSdkVersion 31
@ -76,7 +76,7 @@ fun Context.hasConnectPermission() = getConnectPermissions().isEmpty()
/** /**
* Bluetooth scan/discovery permissions (or empty if we already have what we need) * Bluetooth scan/discovery permissions (or empty if we already have what we need)
*/ */
fun Context.getScanPermissions(): List<String> { fun Context.getScanPermissions(): Array<String> {
val perms = mutableListOf<String>() val perms = mutableListOf<String>()
/* TODO - wait for targetSdkVersion 31 /* TODO - wait for targetSdkVersion 31
@ -101,7 +101,7 @@ fun Context.hasScanPermission() = getScanPermissions().isEmpty()
/** /**
* Camera permission (or empty if we already have what we need) * Camera permission (or empty if we already have what we need)
*/ */
fun Context.getCameraPermissions(): List<String> { fun Context.getCameraPermissions(): Array<String> {
val perms = mutableListOf(Manifest.permission.CAMERA) val perms = mutableListOf(Manifest.permission.CAMERA)
return getMissingPermissions(perms) return getMissingPermissions(perms)
@ -113,7 +113,7 @@ fun Context.hasCameraPermission() = getCameraPermissions().isEmpty()
/** /**
* Location permission (or empty if we already have what we need) * Location permission (or empty if we already have what we need)
*/ */
fun Context.getLocationPermissions(): List<String> { fun Context.getLocationPermissions(): Array<String> {
val perms = mutableListOf(Manifest.permission.ACCESS_FINE_LOCATION) val perms = mutableListOf(Manifest.permission.ACCESS_FINE_LOCATION)
return getMissingPermissions(perms) return getMissingPermissions(perms)
@ -125,8 +125,8 @@ fun Context.hasLocationPermission() = getLocationPermissions().isEmpty()
/** /**
* A list of missing background location permissions (or empty if we already have what we need) * A list of missing background location permissions (or empty if we already have what we need)
*/ */
fun Context.getBackgroundPermissions(): List<String> { fun Context.getBackgroundPermissions(): Array<String> {
val perms = mutableListOf<String>() val perms = mutableListOf(Manifest.permission.ACCESS_FINE_LOCATION)
if (Build.VERSION.SDK_INT >= 29) // only added later if (Build.VERSION.SDK_INT >= 29) // only added later
perms.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION) perms.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION)

Wyświetl plik

@ -1,6 +1,5 @@
package com.geeksville.mesh.ui package com.geeksville.mesh.ui
import android.Manifest
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.Intent import android.content.Intent
import android.graphics.ColorMatrix import android.graphics.ColorMatrix
@ -25,6 +24,7 @@ import com.geeksville.mesh.AppOnlyProtos
import com.geeksville.mesh.ChannelProtos import com.geeksville.mesh.ChannelProtos
import com.geeksville.mesh.ConfigProtos import com.geeksville.mesh.ConfigProtos
import com.geeksville.mesh.R import com.geeksville.mesh.R
import com.geeksville.mesh.android.getCameraPermissions
import com.geeksville.mesh.android.hasCameraPermission import com.geeksville.mesh.android.hasCameraPermission
import com.geeksville.mesh.databinding.ChannelFragmentBinding import com.geeksville.mesh.databinding.ChannelFragmentBinding
import com.geeksville.mesh.model.Channel import com.geeksville.mesh.model.Channel
@ -219,12 +219,11 @@ class ChannelFragment : ScreenFragment("Channel"), Logging {
debug("Camera permission denied") debug("Camera permission denied")
} }
.setPositiveButton(getString(R.string.accept)) { _, _ -> .setPositiveButton(getString(R.string.accept)) { _, _ ->
requestPermissionAndScanLauncher.launch(Manifest.permission.CAMERA) requestPermissionAndScanLauncher.launch(requireContext().getCameraPermissions())
} }
.show() .show()
} }
private fun mlkitScan() { private fun mlkitScan() {
debug("Starting ML Kit QR code scanner") debug("Starting ML Kit QR code scanner")
val options = GmsBarcodeScannerOptions.Builder() val options = GmsBarcodeScannerOptions.Builder()
@ -368,8 +367,8 @@ class ChannelFragment : ScreenFragment("Channel"), Logging {
} }
private val requestPermissionAndScanLauncher = private val requestPermissionAndScanLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { allowed -> registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
if (allowed) zxingScan() if (permissions.entries.all { it.value == true }) zxingScan()
} }
// Register zxing launcher and result handler // Register zxing launcher and result handler

Wyświetl plik

@ -793,11 +793,9 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
binding.provideLocationCheckbox.setOnCheckedChangeListener { view, isChecked -> binding.provideLocationCheckbox.setOnCheckedChangeListener { view, isChecked ->
if (view.isPressed && isChecked) { // We want to ignore changes caused by code (as opposed to the user) if (view.isPressed && isChecked) { // We want to ignore changes caused by code (as opposed to the user)
// Don't check the box until the system setting changes // Don't check the box until the system setting changes
view.isChecked = myActivity.hasLocationPermission() && myActivity.hasBackgroundPermission() view.isChecked = myActivity.hasBackgroundPermission()
if (!myActivity.hasLocationPermission()) // Make sure we have location permission (prerequisite) if (!myActivity.hasBackgroundPermission())
myActivity.requestLocationPermission()
else if (!myActivity.hasBackgroundPermission())
MaterialAlertDialogBuilder(requireContext()) MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.background_required) .setTitle(R.string.background_required)
.setMessage(R.string.why_background_required) .setMessage(R.string.why_background_required)
@ -805,7 +803,12 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
debug("User denied background permission") debug("User denied background permission")
} }
.setPositiveButton(getString(R.string.accept)) { _, _ -> .setPositiveButton(getString(R.string.accept)) { _, _ ->
myActivity.requestBackgroundPermission() // Make sure we have location permission (prerequisite)
if (!myActivity.hasLocationPermission()) {
requestLocationAndBackgroundLauncher.launch(myActivity.getLocationPermissions())
} else {
requestBackgroundAndCheckLauncher.launch(myActivity.getBackgroundPermissions())
}
} }
.show() .show()
if (view.isChecked) { if (view.isChecked) {
@ -940,6 +943,23 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
} }
} }
private val requestLocationAndBackgroundLauncher =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
if (permissions.entries.all { it.value == true }) {
// Older versions of android only need Location permission
if (myActivity.hasBackgroundPermission()) {
binding.provideLocationCheckbox.isChecked = true
} else requestBackgroundAndCheckLauncher.launch(myActivity.getBackgroundPermissions())
}
}
private val requestBackgroundAndCheckLauncher =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
if (permissions.entries.all { it.value == true }) {
binding.provideLocationCheckbox.isChecked = true
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)