|
1 | 1 | package com.juul.kable |
2 | 2 |
|
| 3 | +import android.bluetooth.BluetoothAdapter |
3 | 4 | import android.bluetooth.BluetoothAdapter.STATE_OFF |
| 5 | +import android.bluetooth.BluetoothAdapter.STATE_ON |
| 6 | +import android.bluetooth.BluetoothAdapter.STATE_TURNING_OFF |
| 7 | +import android.bluetooth.BluetoothAdapter.STATE_TURNING_ON |
4 | 8 | import android.bluetooth.BluetoothDevice |
5 | 9 | import android.bluetooth.BluetoothGatt |
6 | 10 | import android.bluetooth.BluetoothGattCharacteristic.PROPERTY_INDICATE |
@@ -197,6 +201,7 @@ public class AndroidPeripheral internal constructor( |
197 | 201 |
|
198 | 202 | public override suspend fun connect() { |
199 | 203 | check(job.isNotCancelled) { "Cannot connect, scope is cancelled for $this" } |
| 204 | + checkBluetoothAdapterState(expected = STATE_ON) |
200 | 205 | connectJob.updateAndGet { it ?: connectAsync() }!!.await() |
201 | 206 | } |
202 | 207 |
|
@@ -377,3 +382,26 @@ private val PlatformCharacteristic.supportsNotify: Boolean |
377 | 382 |
|
378 | 383 | private val PlatformCharacteristic.supportsIndicate: Boolean |
379 | 384 | get() = bluetoothGattCharacteristic.properties and PROPERTY_INDICATE != 0 |
| 385 | + |
| 386 | +/** |
| 387 | + * Explicitly check the adapter state before connecting in order to respect system settings. |
| 388 | + * Android doesn't actually turn bluetooth off when the setting is disabled, so without this |
| 389 | + * check we're able to reconnect the device illegally. |
| 390 | + */ |
| 391 | +private fun checkBluetoothAdapterState( |
| 392 | + expected: Int, |
| 393 | +) { |
| 394 | + fun nameFor(value: Int) = when (value) { |
| 395 | + STATE_OFF -> "Off" |
| 396 | + STATE_ON -> "On" |
| 397 | + STATE_TURNING_OFF -> "TurningOff" |
| 398 | + STATE_TURNING_ON -> "TurningOn" |
| 399 | + else -> "Unknown" |
| 400 | + } |
| 401 | + val actual = BluetoothAdapter.getDefaultAdapter().state |
| 402 | + if (expected != actual) { |
| 403 | + val actualName = nameFor(actual) |
| 404 | + val expectedName = nameFor(expected) |
| 405 | + throw BluetoothDisabledException("Bluetooth adapter state is $actualName ($actual), but $expectedName ($expected) was required.") |
| 406 | + } |
| 407 | +} |
0 commit comments