fix: thread safety, GATT cleanup, onResume guard, relay2 docs
This commit is contained in:
parent
404f46acf8
commit
a6e5df0052
3 changed files with 69 additions and 16 deletions
|
|
@ -73,23 +73,23 @@ class BleRelayManager(
|
|||
fun startScan() {
|
||||
if (isScanning) return
|
||||
if (!hasPermissions()) {
|
||||
callbacks.onStatusChanged(BleStatus.PermissionsDenied)
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.PermissionsDenied) }
|
||||
return
|
||||
}
|
||||
val adapter = BluetoothAdapter.getDefaultAdapter()
|
||||
if (adapter == null || !adapter.isEnabled) {
|
||||
callbacks.onStatusChanged(BleStatus.BluetoothDisabled)
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.BluetoothDisabled) }
|
||||
return
|
||||
}
|
||||
loadState()
|
||||
if (hmacKey == null || deviceUuid == null) {
|
||||
callbacks.onStatusChanged(BleStatus.NoKey)
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.NoKey) }
|
||||
return
|
||||
}
|
||||
isScanning = true
|
||||
scanTimedOut = false
|
||||
scanTimeoutRetries = 0
|
||||
callbacks.onStatusChanged(BleStatus.Scanning)
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.Scanning) }
|
||||
val filter = ScanFilter.Builder().setServiceUuid(ParcelUuid(SERVICE_UUID)).build()
|
||||
val settings = ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build()
|
||||
adapter.bluetoothLeScanner.startScan(listOf(filter), settings, scanCallback)
|
||||
|
|
@ -105,6 +105,7 @@ class BleRelayManager(
|
|||
|
||||
@SuppressLint("MissingPermission")
|
||||
fun stopScan() {
|
||||
handler.removeCallbacks(scanRunnable)
|
||||
if (!isScanning) return
|
||||
isScanning = false
|
||||
scanTimeoutRunnable?.let { handler.removeCallbacks(it) }
|
||||
|
|
@ -116,7 +117,7 @@ class BleRelayManager(
|
|||
handler.postDelayed(scanRunnable, 2000L)
|
||||
return
|
||||
}
|
||||
callbacks.onStatusChanged(BleStatus.DeviceNotFound)
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.DeviceNotFound) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,6 +141,9 @@ class BleRelayManager(
|
|||
|
||||
fun destroy() {
|
||||
handler.removeCallbacksAndMessages(null)
|
||||
stopScan()
|
||||
bluetoothGatt?.disconnect()
|
||||
bluetoothGatt?.close()
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
|
|
@ -173,9 +177,14 @@ class BleRelayManager(
|
|||
triedAddresses.clear()
|
||||
}
|
||||
|
||||
fun isConnected(): Boolean {
|
||||
return bluetoothGatt != null
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
private fun connectToDevice(device: android.bluetooth.BluetoothDevice) {
|
||||
callbacks.onStatusChanged(BleStatus.Connecting)
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.Connecting) }
|
||||
Log.d(TAG, "Connecting to ${device.address}")
|
||||
bluetoothGatt = device.connectGatt(context, false, gattCallback)
|
||||
}
|
||||
|
||||
|
|
@ -185,7 +194,7 @@ class BleRelayManager(
|
|||
if (newState == BluetoothProfile.STATE_CONNECTED) {
|
||||
if (hmacKey == null) {
|
||||
Log.w(TAG, "GATT connected but no key -- disconnecting")
|
||||
callbacks.onStatusChanged(BleStatus.NoKey)
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.NoKey) }
|
||||
gatt.disconnect()
|
||||
return
|
||||
}
|
||||
|
|
@ -194,7 +203,7 @@ class BleRelayManager(
|
|||
gatt.discoverServices()
|
||||
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
|
||||
Log.d(TAG, "GATT disconnected")
|
||||
callbacks.onStatusChanged(BleStatus.Disconnected)
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.Disconnected) }
|
||||
gatt.close()
|
||||
bluetoothGatt = null
|
||||
relayCharacteristic = null
|
||||
|
|
@ -207,7 +216,7 @@ class BleRelayManager(
|
|||
override fun onServicesDiscovered(gatt: android.bluetooth.BluetoothGatt, status: Int) {
|
||||
if (status != BluetoothGatt.GATT_SUCCESS) {
|
||||
Log.w(TAG, "Service discovery failed (status=$status)")
|
||||
callbacks.onStatusChanged(BleStatus.ServiceError)
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.ServiceError) }
|
||||
return
|
||||
}
|
||||
Log.d(TAG, "Services discovered, requesting MTU...")
|
||||
|
|
@ -226,11 +235,11 @@ class BleRelayManager(
|
|||
gatt.readCharacteristic(uuidChar)
|
||||
} else {
|
||||
Log.e(TAG, "Service or characteristics not found")
|
||||
callbacks.onStatusChanged(BleStatus.ServiceNotFound)
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.ServiceNotFound) }
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "Service not found")
|
||||
callbacks.onStatusChanged(BleStatus.ServiceNotFound)
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.ServiceNotFound) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -246,11 +255,11 @@ class BleRelayManager(
|
|||
descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
|
||||
gatt.writeDescriptor(descriptor)
|
||||
}
|
||||
callbacks.onStatusChanged(BleStatus.Connected)
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.Connected) }
|
||||
} else {
|
||||
Log.w(TAG, "UUID mismatch -- disconnecting")
|
||||
triedAddresses.add(gatt.device.address)
|
||||
callbacks.onStatusChanged(BleStatus.WrongDevice)
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.WrongDevice) }
|
||||
gatt.disconnect()
|
||||
}
|
||||
}
|
||||
|
|
@ -260,7 +269,7 @@ class BleRelayManager(
|
|||
override fun onCharacteristicWrite(gatt: android.bluetooth.BluetoothGatt, characteristic: android.bluetooth.BluetoothGattCharacteristic, status: Int) {
|
||||
if (status != BluetoothGatt.GATT_SUCCESS) {
|
||||
Log.w(TAG, "Write failed (status=$status)")
|
||||
callbacks.onStatusChanged(BleStatus.CommError)
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.CommError) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,8 +117,10 @@ class MainActivity : AppCompatActivity(), BleCallbacks {
|
|||
requestPermissions()
|
||||
return
|
||||
}
|
||||
manager.resetTriedAddresses()
|
||||
handler.postDelayed({ manager.startScan() }, ON_RESUME_SCAN_DELAY_MS)
|
||||
if (!manager.isConnected()) {
|
||||
manager.resetTriedAddresses()
|
||||
handler.postDelayed({ manager.startScan() }, ON_RESUME_SCAN_DELAY_MS)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue