Android backend does not give each service/characteristic a unique "handle".
See original GitHub issue- bleak version: 0.14.3
- Python version: Python 3.7.13 (Colab)
- Operating System: Samsung SM-G900F Android 6.0.1, API 23
Description
Hello! I am trying to implement an application on an android mobile. This app needs to connect via low-energy bluetooth BLE to a scale (Mi Smart Scale 2) and take the weight. To create the apk of the application I use Colab. The problem is that when I launch the application it crashes immediately after starting and I cannot read the weight.
What I Did
import asyncio
from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from bleak import BleakClient
kv = '''
WindowManager:
MainWindow:
BluetoothWindow:
LoginWindow:
<LoginWindow>:
name: "login"
email: email
password: password
FloatLayout:
Label:
text:"Email: "
font_size: (root.width**2 + root.height**2) / 13**4
pos_hint: {"x":0.1, "top":0.9}
size_hint: 0.35, 0.15
TextInput:
id: email
font_size: (root.width**2 + root.height**2) / 13**4
multiline: False
pos_hint: {"x": 0.45 , "top":0.9}
size_hint: 0.4, 0.15
Label:
text:"Password: "
font_size: (root.width**2 + root.height**2) / 13**4
pos_hint: {"x":0.1, "top":0.7}
size_hint: 0.35, 0.15
TextInput:
id: password
font_size: (root.width**2 + root.height**2) / 13**4
multiline: False
password: True
pos_hint: {"x": 0.45, "top":0.7}
size_hint: 0.4, 0.15
Button:
pos_hint:{"x":0.2,"y":0.05}
size_hint: 0.6, 0.2
font_size: (root.width**2 + root.height**2) / 13**4
text: "Login"
on_release:
app.root.current = "main"
root.manager.transition.direction = "left"
Button:
pos_hint:{"x":0.2,"y":0.3}
size_hint: 0.6, 0.1
font_size: (root.width**2 + root.height**2) / 17**4
text: "Non hai un account? Creane uno"
on_release:
<MainWindow>:
name: "main"
BoxLayout:
orientation: "vertical"
size: root.width, root.height
FloatLayout:
n: n
email: email
created:created
FloatLayout:
Label:
id: n
pos_hint:{"x": 0.1, "top":0.9}
size_hint:0.8, 0.2
text: "Nome account: "
Label:
id: email
pos_hint:{"x": 0.1, "top":0.7}
size_hint:0.8, 0.2
text: "Email: "
Label:
id: created
pos_hint:{"x": 0.1, "top":0.5}
size_hint:0.8, 0.2
text: "Creato il: "
Button:
pos_hint:{"x":0.35, "y": 0.2}
size_hint:0.3,0.1
text: "Log Out"
on_release:
app.root.current = "login"
root.manager.transition.direction = "right"
Button:
pos_hint:{"x":0.35, "y": 0.1}
size_hint:0.3,0.1
text: "Log In"
on_release:
app.root.current = "ble"
root.manager.transition.direction = "left"
<BluetoothWindow>:
name: "ble"
peso: peso
BoxLayout:
orientation: "vertical"
size: root.width, root.height
FloatLayout:
Label:
id: peso
pos_hint:{"x": 0.1, "top":0.7}
size_hint:0.8, 0.2
text: "peso: "
Button:
pos_hint:{"x":0.2, "y": 0.1}
size_hint:0.6,0.2
text: "Log Out"
on_release:
app.root.current = "main"
root.manager.transition.direction = "right"
'''
class LoginWindow(Screen):
pass
class MainWindow(Screen):
pass
class BluetoothWindow(Screen):
peso = ObjectProperty(None)
def on_enter(self):
self.peso.text = "peso: " + str(data2)
class WindowManager(ScreenManager):
pass
sm = WindowManager()
screens = [MainWindow(name="main"),
BluetoothWindow(name="ble"),
LoginWindow(name="login")]
for screen in screens:
sm.add_widget(screen)
sm.current = "main"
class AsyncApp(App):
other_task = None
def build(self):
return Builder.load_string(kv)
def build2(self):
return sm
def app_func(self):
'''This will run both methods asynchronously and then block until they
are finished
'''
self.other_task = asyncio.ensure_future(self.get_the_weight_from_the_mi_smart_scale_2())
async def run_wrapper():
# we don't actually need to set asyncio as the lib because it is
# the default, but it doesn't hurt to be explicit
await self.async_run(async_lib='asyncio')
print('App done')
self.other_task.cancel()
return asyncio.gather(run_wrapper(), self.other_task)
global notification_handler
def notification_handler(sender, data):
"""Simple notification handler which prints the data received."""
data1 = list(data)
global data2
data2 = ((data1[1]+data1[2]*256)*0.005)
print("{0}: {1}".format(sender, data2))
async def get_the_weight_from_the_mi_smart_scale_2(self):
#da modificare
'''This method is also run by the asyncio loop and periodically prints
something.
'''
async with BleakClient("70:87:9e:0f:f8:7d") as client:
print(f"Connected: {client.is_connected}")
await client.start_notify("00002a9d-0000-1000-8000-00805f9b34fb", notification_handler)
await asyncio.sleep(30.0)
await client.stop_notify("00002a9d-0000-1000-8000-00805f9b34fb")
print(f"Connected: {client.is_connected}")
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(AsyncApp().app_func())
loop.close()
### What I read on Android Studio's log######################################
2022-07-13 15:53:26.187 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 3
2022-07-13 15:53:26.187 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 3
2022-07-13 15:53:26.187 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 3
2022-07-13 15:53:26.187 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 3
2022-07-13 15:53:26.187 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 4
2022-07-13 15:53:26.187 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.187 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 3
2022-07-13 15:53:26.187 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 3
2022-07-13 15:53:26.187 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 3
2022-07-13 15:53:26.187 1983-2477/? W/bt_btif: bta_le_client_conn_param_cback, status : 0
2022-07-13 15:53:26.187 1983-2477/? W/bt_btif: bta_le_client_conn_param_cback, clcb found and client_if : 10
2022-07-13 15:53:26.187 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 3
2022-07-13 15:53:26.187 1983-2204/? D/BtGatt.GattService: onClientConnParamsChanged() - clientIf=10 address=70:87:9E:0F:F8:7D, interval=39status=0
2022-07-13 15:53:26.187 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 3
2022-07-13 15:53:26.187 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 4
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.197 14122-14134/org.test.tesi4 D/BluetoothGatt: onClientConnParamsChanged() - Device=70:87:9E:0F:F8:7D interval=39 status=0
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 5
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 5
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 5
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 5
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.197 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.207 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 5
2022-07-13 15:53:26.207 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.207 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 5
2022-07-13 15:53:26.207 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.207 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 5
2022-07-13 15:53:26.207 1983-2415/? D/BtGatt.GattService: [gattSrvHandler] msg : 2
2022-07-13 15:53:26.207 14122-14134/org.test.tesi4 D/BluetoothGatt: onSearchComplete() = Device=70:87:9E:0F:F8:7D Status=0
2022-07-13 15:53:26.277 1983-2493/? D/bt_upio: ..proc_btwrite_timeout..
2022-07-13 15:53:26.277 1983-2493/? D/bt_upio: upio_set : pio 0 action 1, polarity 1
2022-07-13 15:53:26.357 14122-14150/org.test.tesi4 I/python: Connected: True
2022-07-13 15:53:26.357 14122-14150/org.test.tesi4 D/BluetoothGatt: cancelOpen() - device: 70:87:9E:0F:F8:7D
2022-07-13 15:53:26.367 1983-2015/? D/BtGatt.GattService: clientDisconnect() - address=70:87:9E:0F:F8:7D, connId=10
2022-07-13 15:53:26.367 1983-2477/? E/bt_btm: btm_ble_get_search_if search_if=4
2022-07-13 15:53:26.367 1983-2417/? D/bt_vendor: op for 7
2022-07-13 15:53:26.367 836-2532/? V/AlarmManager: remove PendingIntent] PendingIntent{ec8bcc: PendingIntentRecord{83cd4dc com.android.bluetooth broadcastIntent}}
2022-07-13 15:53:26.367 1983-2417/? D/bt_upio: upio_set : pio 0 action 2, polarity 1
2022-07-13 15:53:26.367 1983-2477/? W/bt_btif: bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x0016
2022-07-13 15:53:26.367 1983-2417/? D/bt_upio: upio_start_stop_timer : timer_settime success
2022-07-13 15:53:26.367 1983-2477/? W/bt_btif: bta_gattc_conn_cback() - cif=5 connected=0 conn_id=5 reason=0x0016
2022-07-13 15:53:26.367 1983-2477/? W/bt_btif: bta_gattc_conn_cback() - cif=6 connected=0 conn_id=6 reason=0x0016
2022-07-13 15:53:26.367 1983-2477/? W/bt_btif: bta_gattc_conn_cback() - cif=7 connected=0 conn_id=7 reason=0x0016
2022-07-13 15:53:26.367 1983-2477/? W/bt_btif: bta_gattc_conn_cback() - cif=8 connected=0 conn_id=8 reason=0x0016
2022-07-13 15:53:26.367 1983-2477/? W/bt_btif: bta_gattc_conn_cback() - cif=9 connected=0 conn_id=9 reason=0x0016
2022-07-13 15:53:26.367 1983-2417/? D/bt_upio: upio_set: proc btwrite assertion, buffer: 1, timer_armed 1 1
2022-07-13 15:53:26.367 1983-2477/? W/bt_btif: bta_gattc_conn_cback() - cif=10 connected=0 conn_id=10 reason=0x0016
2022-07-13 15:53:26.367 1983-2477/? E/bt_btif: bta_gattc_mark_bg_conn unable to find the bg connection mask for: 70:87:9e:0f:f8:7d
2022-07-13 15:53:26.367 1983-2204/? D/BtGatt.GattService: onDisconnected() - clientIf=10, connId=10, address=70:87:9E:0F:F8:7D
2022-07-13 15:53:26.367 14122-14157/org.test.tesi4 D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=10 device=70:87:9E:0F:F8:7D
2022-07-13 15:53:26.367 14122-14150/org.test.tesi4 D/BluetoothGatt: close()
2022-07-13 15:53:26.367 14122-14150/org.test.tesi4 D/BluetoothGatt: unregisterApp() - mClientIf=10
2022-07-13 15:53:26.377 1983-2505/? D/BtGatt.GattService: unregisterClient() - clientIf=10
2022-07-13 15:53:26.377 14122-14150/org.test.tesi4 I/python: Traceback (most recent call last):
2022-07-13 15:53:26.377 14122-14150/org.test.tesi4 I/python: File "/content/.buildozer/android/app/main.py", line 228, in <module>
2022-07-13 15:53:26.377 836-1510/? V/AlarmManager: remove PendingIntent] PendingIntent{317de15: PendingIntentRecord{83cd4dc com.android.bluetooth broadcastIntent}}
2022-07-13 15:53:26.377 14122-14150/org.test.tesi4 I/python: File "/content/.buildozer/android/platform/build-armeabi-v7a/build/other_builds/python3/armeabi-v7a__ndk_target_21/python3/Lib/asyncio/base_events.py", line 616, in run_until_complete
2022-07-13 15:53:26.377 14122-14150/org.test.tesi4 I/python: File "/content/.buildozer/android/app/main.py", line 216, in get_the_weight_from_the_mi_smart_scale_2
2022-07-13 15:53:26.377 14122-14150/org.test.tesi4 I/python: File "/content/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/tesi4/armeabi-v7a/bleak/backends/p4android/client.py", line 486, in start_notify
2022-07-13 15:53:26.377 14122-14150/org.test.tesi4 I/python: bleak.exc.BleakError: Characteristic with UUID 00002a9d-0000-1000-8000-00805f9b34fb could not be found!
2022-07-13 15:53:26.377 14122-14150/org.test.tesi4 I/python: Python for android ended.
2022-07-13 15:53:26.387 1983-2477/? I/bt_btm_sec: btm_sec_disconnected clearing pending flag handle:64 reason:22
Issue Analytics
- State:
- Created a year ago
- Comments:20
Top Results From Across the Web
Best practices for unique identifiers - Android Developers
There are some key points to bear in mind, however, when you use this ID: Always respect the user's intention in resetting the...
Read more >Service | Android Developers
A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise...
Read more >Services overview | Android Developers
A Service is an application component that can perform long-running operations in the background. It does not provide a user interface.
Read more >Background Work Overview | Android Developers
Likewise, background work in each of these three categories can be either ... work through WorkManager is the best way to handle tasks...
Read more >Permissions on Android - Android Developers
The Special app access page in system settings contains a set of user-toggleable operations. Many of these operations are implemented as special permissions....
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
The bug in Bleak needs to be fixed. All characteristics in the dictionary are using the same key which writes over the previous key, so only the last discovered characteristic can be used currently.
If Android doesn’t see the characteristic at all, e.g. with the nRF Connect app, then you need to log Bluetooth packets to see what is going on.
This shows there is only one characteristic with handle
0
which doesn’t seem right. I think we assumed thatgetInstanceId()
returned the handle, but I think that it just returns a number that is unique per characteristics with the same UUID. That is, it returns 0 for most characteristics and 1 for the second instance of a characteristic with the same UUID as an already seen characteristic.So, to fix this, I think we need to create a mapping between a tuple containing the UUID and instance id to a “handle” integer value to be compatible with other Bleak backends.