fix(bluetooth): Check for permissions before accessing bonded devices (#3720)

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
James Rich 2025-11-17 06:35:33 -06:00 committed by GitHub
parent d6f39fdcb5
commit 12ccb34553
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 17 additions and 14 deletions

View file

@ -160,11 +160,13 @@ constructor(
Timber.d("Detected our bluetooth access=$newState")
}
private fun getBondedAppPeripherals(enabled: Boolean): List<Peripheral> = if (enabled) {
centralManager.getBondedPeripherals().filter(::isMatchingPeripheral)
} else {
emptyList()
}
@SuppressLint("MissingPermission")
private fun getBondedAppPeripherals(enabled: Boolean): List<Peripheral> =
if (enabled && application.hasBluetoothPermission()) {
centralManager.getBondedPeripherals().filter(::isMatchingPeripheral)
} else {
emptyList()
}
/** Checks if a peripheral is one of ours, either by its advertised name or by the services it provides. */
@OptIn(ExperimentalUuidApi::class)

View file

@ -19,7 +19,6 @@ package com.geeksville.mesh.ui.connections.components
import android.Manifest
import android.content.Intent
import android.os.Build
import android.provider.Settings.ACTION_BLUETOOTH_SETTINGS
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
@ -39,6 +38,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
@ -50,6 +50,7 @@ import com.geeksville.mesh.model.DeviceListEntry
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.MultiplePermissionsState
import com.google.accompanist.permissions.rememberMultiplePermissionsState
import kotlinx.coroutines.launch
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.service.ConnectionState
import org.meshtastic.core.strings.Res
@ -64,6 +65,7 @@ import org.meshtastic.core.strings.permission_missing_31
import org.meshtastic.core.strings.scan
import org.meshtastic.core.strings.scanning_bluetooth
import org.meshtastic.core.ui.component.TitledCard
import org.meshtastic.core.ui.util.showToast
/**
* Composable that displays a list of Bluetooth Low Energy (BLE) devices and allows scanning. It handles Bluetooth
@ -90,23 +92,22 @@ fun BLEDevices(
// Define permissions needed for Bluetooth scanning based on Android version.
val bluetoothPermissionsList = remember {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
listOf(Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT)
} else {
// ACCESS_FINE_LOCATION is required for Bluetooth scanning on pre-S devices.
listOf(Manifest.permission.ACCESS_FINE_LOCATION)
}
listOf(Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT)
}
val context = LocalContext.current
val permsMissing = stringResource(Res.string.permission_missing)
val coroutineScope = rememberCoroutineScope()
val permissionsState =
rememberMultiplePermissionsState(
permissions = bluetoothPermissionsList,
onPermissionsResult = {
if (it.values.all { granted -> granted } && bluetoothEnabled) {
scanModel.startScan()
scanModel.refreshPermissions()
scanModel.startScan()
} else {
// If permissions are not granted, we can show a message or handle it accordingly.
coroutineScope.launch { context.showToast(permsMissing) }
}
},
)