Closed robgar2001 closed 2 years ago
Thanks @robgar2001 Seems like a reasonable fix. I will check disconnecting scenarios on my devices.
I like the idea to simplify the reconnection management,
but closing GATT and restart scan is not always desired approach.
It is possible to try to reconnect to device using existing BluetoothGatt
object: https://developer.android.com/reference/android/bluetooth/BluetoothGatt#connect()
For example:
from kivy.app import App
from kivy.clock import Clock
from kivy.logger import Logger
from kivy.uix.widget import Widget
from able import BluetoothDispatcher, GATT_SUCCESS
class BLESender(BluetoothDispatcher):
def __init__(self):
super().__init__()
self._connected = False
Clock.schedule_once(self.restart_scan_if_needed, 0)
def on_device(self, device, rssi, advertisement):
if device.getName() == "KivyBLETest":
self.device = device
self.stop_scan()
def on_scan_completed(self):
if self.device:
self.connect_gatt(self.device)
def on_connection_state_change(self, status, state):
Logger.info("Connection state changed <%d> <%d>", status, state)
if state and status == GATT_SUCCESS:
self._connected = True
else:
self._connected = False
Logging.info("Initiate reconnection")
self.gatt.connect()
# After 20 seconds check if reconnection was successful
Clock.schedule_once(self.restart_scan_if_needed, 20)
def restart_scan_if_needed(self, *args, **kwargs):
if not self._connected:
Logger.info("Start scan")
self.device = None
self.close_gatt() # Close the connection,
self.start_scan() # and start scan again
class ExampleApp(App):
def build(self):
BLESender()
return Widget()
if __name__ == '__main__':
ExampleApp().run()
@robgar2001 what do you think, maybe this approach can be used in your application?
HI @b3b
Thanks for replying! I see what you mean.
Calling BluetoothGatt.connect() or closeGatt() in the disconnected state still feels a bit odd. Since able is meant as an interface to the android ble api, sticking to the android.developer docs seems the right solution.
Maybe a slight logging improvement to inform people would do wonders?
@robgar2001 great, it can help users to debug if issue is happen. I open #34 for possible steps to document and mitigate re-connection error.
ABLE was not able to reconnect when walking out of range.
This was due to the connectGatt method. After walking out of range, the mBluetoothGatt object was not equal to null. Thereby blocking the ability to reconnect. When walking of out range, the onConnectionStateChanged method is called. In my case with state disconnected en status 8. To fix the connectGatt problem, it is sufficient to close the gatt connection when onConnectionStateChanged is called with state argument STATE_DISCONNECTED.