comboctl-android: Check that the adapter is available and enabled
Signed-off-by: Carlos Rafael Giani <crg7475@mailbox.org>
This commit is contained in:
parent
13666fd549
commit
c1058ad113
1 changed files with 35 additions and 11 deletions
|
@ -7,8 +7,10 @@ import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import info.nightscout.comboctl.base.BluetoothAddress
|
import info.nightscout.comboctl.base.BluetoothAddress
|
||||||
import info.nightscout.comboctl.base.BluetoothDevice
|
import info.nightscout.comboctl.base.BluetoothDevice
|
||||||
|
import info.nightscout.comboctl.base.BluetoothNotEnabledException
|
||||||
import info.nightscout.comboctl.base.BluetoothException
|
import info.nightscout.comboctl.base.BluetoothException
|
||||||
import info.nightscout.comboctl.base.BluetoothInterface
|
import info.nightscout.comboctl.base.BluetoothInterface
|
||||||
|
import info.nightscout.comboctl.base.BluetoothNotAvailableException
|
||||||
import info.nightscout.comboctl.base.LogLevel
|
import info.nightscout.comboctl.base.LogLevel
|
||||||
import info.nightscout.comboctl.base.Logger
|
import info.nightscout.comboctl.base.Logger
|
||||||
import info.nightscout.comboctl.base.toBluetoothAddress
|
import info.nightscout.comboctl.base.toBluetoothAddress
|
||||||
|
@ -35,7 +37,10 @@ private val logger = Logger.get("AndroidBluetoothInterface")
|
||||||
* instance is an ideal choice.
|
* instance is an ideal choice.
|
||||||
*/
|
*/
|
||||||
class AndroidBluetoothInterface(private val androidContext: Context) : BluetoothInterface {
|
class AndroidBluetoothInterface(private val androidContext: Context) : BluetoothInterface {
|
||||||
private var bluetoothAdapter: SystemBluetoothAdapter? = null
|
private var _bluetoothAdapter: SystemBluetoothAdapter? = null
|
||||||
|
private val bluetoothAdapter: SystemBluetoothAdapter
|
||||||
|
get() = _bluetoothAdapter ?: throw BluetoothNotAvailableException()
|
||||||
|
|
||||||
private var rfcommServerSocket: SystemBluetoothServerSocket? = null
|
private var rfcommServerSocket: SystemBluetoothServerSocket? = null
|
||||||
private var discoveryStarted = false
|
private var discoveryStarted = false
|
||||||
private var discoveryBroadcastReceiver: BroadcastReceiver? = null
|
private var discoveryBroadcastReceiver: BroadcastReceiver? = null
|
||||||
|
@ -96,11 +101,16 @@ class AndroidBluetoothInterface(private val androidContext: Context) : Bluetooth
|
||||||
else @Suppress("DEPRECATION") getParcelableExtra(name)
|
else @Suppress("DEPRECATION") getParcelableExtra(name)
|
||||||
|
|
||||||
fun setup() {
|
fun setup() {
|
||||||
val bluetoothManager = androidContext.getSystemService(Context.BLUETOOTH_SERVICE) as SystemBluetoothManager
|
val bluetoothManager = androidContext.getSystemService(Context.BLUETOOTH_SERVICE) as? SystemBluetoothManager
|
||||||
bluetoothAdapter = bluetoothManager.adapter
|
_bluetoothAdapter = bluetoothManager?.adapter
|
||||||
|
|
||||||
|
checkIfBluetoothEnabledAndAvailable()
|
||||||
|
|
||||||
val bondedDevices = checkForConnectPermission(androidContext) {
|
val bondedDevices = checkForConnectPermission(androidContext) {
|
||||||
bluetoothAdapter!!.bondedDevices
|
// The "not enabled" check above is important, because in the disabled
|
||||||
|
// state, the adapter returns an empty list here. This would mislead
|
||||||
|
// the logic below into thinking that there are no bonded devices.
|
||||||
|
bluetoothAdapter.bondedDevices
|
||||||
}
|
}
|
||||||
|
|
||||||
logger(LogLevel.DEBUG) { "Found ${bondedDevices.size} bonded Bluetooth device(s)" }
|
logger(LogLevel.DEBUG) { "Found ${bondedDevices.size} bonded Bluetooth device(s)" }
|
||||||
|
@ -180,7 +190,7 @@ class AndroidBluetoothInterface(private val androidContext: Context) : Bluetooth
|
||||||
// necessary for correct function, just a detail for sake of completeness.)
|
// necessary for correct function, just a detail for sake of completeness.)
|
||||||
logger(LogLevel.DEBUG) { "Setting up RFCOMM listener socket" }
|
logger(LogLevel.DEBUG) { "Setting up RFCOMM listener socket" }
|
||||||
rfcommServerSocket = checkForConnectPermission(androidContext) {
|
rfcommServerSocket = checkForConnectPermission(androidContext) {
|
||||||
bluetoothAdapter!!.listenUsingInsecureRfcommWithServiceRecord(
|
bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(
|
||||||
sdpServiceName,
|
sdpServiceName,
|
||||||
Constants.sdpSerialPortUUID
|
Constants.sdpSerialPortUUID
|
||||||
)
|
)
|
||||||
|
@ -203,7 +213,7 @@ class AndroidBluetoothInterface(private val androidContext: Context) : Bluetooth
|
||||||
logger(LogLevel.DEBUG) { "Closing accepted incoming RFCOMM socket" }
|
logger(LogLevel.DEBUG) { "Closing accepted incoming RFCOMM socket" }
|
||||||
try {
|
try {
|
||||||
socket.close()
|
socket.close()
|
||||||
} catch (e: IOException) {
|
} catch (_: IOException) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -274,20 +284,24 @@ class AndroidBluetoothInterface(private val androidContext: Context) : Bluetooth
|
||||||
stopDiscoveryInternal()
|
stopDiscoveryInternal()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDevice(deviceAddress: BluetoothAddress): BluetoothDevice =
|
override fun getDevice(deviceAddress: BluetoothAddress): BluetoothDevice {
|
||||||
AndroidBluetoothDevice(androidContext, bluetoothAdapter!!, deviceAddress)
|
checkIfBluetoothEnabledAndAvailable()
|
||||||
|
return AndroidBluetoothDevice(androidContext, bluetoothAdapter, deviceAddress)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getAdapterFriendlyName() =
|
override fun getAdapterFriendlyName() =
|
||||||
checkForConnectPermission(androidContext) { bluetoothAdapter!!.name }
|
checkForConnectPermission(androidContext) { bluetoothAdapter.name }
|
||||||
?: throw BluetoothException("Could not get Bluetooth adapter friendly name")
|
?: throw BluetoothException("Could not get Bluetooth adapter friendly name")
|
||||||
|
|
||||||
override fun getPairedDeviceAddresses(): Set<BluetoothAddress> =
|
override fun getPairedDeviceAddresses(): Set<BluetoothAddress> {
|
||||||
try {
|
checkIfBluetoothEnabledAndAvailable()
|
||||||
|
return try {
|
||||||
deviceAddressLock.lock()
|
deviceAddressLock.lock()
|
||||||
pairedDeviceAddresses.filter { pairedDeviceAddress -> deviceFilterCallback(pairedDeviceAddress) }.toSet()
|
pairedDeviceAddresses.filter { pairedDeviceAddress -> deviceFilterCallback(pairedDeviceAddress) }.toSet()
|
||||||
} finally {
|
} finally {
|
||||||
deviceAddressLock.unlock()
|
deviceAddressLock.unlock()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun stopDiscoveryInternal() {
|
private fun stopDiscoveryInternal() {
|
||||||
// Close the server socket. This frees RFCOMM resources and ends
|
// Close the server socket. This frees RFCOMM resources and ends
|
||||||
|
@ -332,6 +346,16 @@ class AndroidBluetoothInterface(private val androidContext: Context) : Bluetooth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkIfBluetoothEnabledAndAvailable() {
|
||||||
|
// Trying to access bluetoothAdapter here if it is currently null will
|
||||||
|
// automatically cause BluetoothNotAvailableException to be thrown,
|
||||||
|
// so that case is also covered implicitly by this code.
|
||||||
|
if (!bluetoothAdapter.isEnabled || (bluetoothAdapter.state != SystemBluetoothAdapter.STATE_ON)) {
|
||||||
|
logger(LogLevel.ERROR) { "Bluetooth is not enabled" }
|
||||||
|
throw BluetoothNotEnabledException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun onAclConnected(intent: Intent, foundNewPairedDevice: (deviceAddress: BluetoothAddress) -> Unit) {
|
private fun onAclConnected(intent: Intent, foundNewPairedDevice: (deviceAddress: BluetoothAddress) -> Unit) {
|
||||||
// Sanity check in case we get this notification for the
|
// Sanity check in case we get this notification for the
|
||||||
// device already and need to avoid duplicate processing.
|
// device already and need to avoid duplicate processing.
|
||||||
|
|
Loading…
Reference in a new issue