From ca2cae70035f1b960e4c3c2b3bb7cda53b8310d7 Mon Sep 17 00:00:00 2001 From: geeksville Date: Thu, 23 Apr 2020 08:52:25 -0700 Subject: [PATCH] Don't claim we have bluetooth access until the user grants location permissions. This fixes an ugly behavior when for when the user does a from scratch install and first runs the app (and the dialog comes up to grant access). Previously we were starting our BLE scan for devices before that dialog has been approved by the user, which Android doesn't return an error for it instead just silently refuses to show devices. If the user switched away from the app and came back, we'd restart our scan and they could see their device. This fixes things so that the user doesn't have to switch away from our app once before the devices appear. --- .../java/com/geeksville/mesh/MainActivity.kt | 49 +++++++++++++++---- .../geeksville/mesh/ui/SettingsFragment.kt | 2 +- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index b464ff9e6..6e95e756a 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -167,10 +167,47 @@ class MainActivity : AppCompatActivity(), Logging, } } + private val btStateReceiver = BluetoothStateReceiver { enabled -> + updateBluetoothEnabled() + } + + + /** + * Don't tell our app we have bluetooth until we have bluetooth _and_ location access + */ + private fun updateBluetoothEnabled() { + var enabled = false // assume failure + + val requiredPerms = listOf( + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.BLUETOOTH, + Manifest.permission.BLUETOOTH_ADMIN + ) + + + if (getMissingPermissions(requiredPerms).isEmpty()) { + /// ask the adapter if we have access + bluetoothAdapter?.apply { + enabled = isEnabled + } + } else + errormsg("Still missing needed bluetooth permissions") + + debug("Detected our bluetooth access=$enabled") model.bluetoothEnabled.value = enabled } + /** + * return a list of the permissions we don't have + */ + private fun getMissingPermissions(perms: List) = perms.filter { + ContextCompat.checkSelfPermission( + this, + it + ) != PackageManager.PERMISSION_GRANTED + } + private fun requestPermission() { debug("Checking permissions") @@ -194,12 +231,7 @@ class MainActivity : AppCompatActivity(), Logging, perms.add(Manifest.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND) } - val missingPerms = perms.filter { - ContextCompat.checkSelfPermission( - this, - it - ) != PackageManager.PERMISSION_GRANTED - } + val missingPerms = getMissingPermissions(perms) if (missingPerms.isNotEmpty()) { missingPerms.forEach { // Permission is not granted @@ -255,6 +287,7 @@ class MainActivity : AppCompatActivity(), Logging, Toast.LENGTH_LONG ).show() } + updateBluetoothEnabled() } @@ -313,9 +346,7 @@ class MainActivity : AppCompatActivity(), Logging, model.ownerName.value = prefs.getString("owner", "")!! /// Set initial bluetooth state - bluetoothAdapter?.apply { - model.bluetoothEnabled.value = isEnabled - } + updateBluetoothEnabled() /// We now want to be informed of bluetooth state registerReceiver(btStateReceiver, btStateReceiver.intent) diff --git a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt index 8fe511503..0996b0fcb 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt @@ -518,7 +518,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { override fun onResume() { super.onResume() - if (!hasCompanionDeviceApi) + if (!hasCompanionDeviceApi && model.bluetoothEnabled.value!!) scanModel.startScan() } }