Android backend (BeeWare)
This backend is intended for Android apps using the BeeWare toolchain:
Briefcase is used to build the application. Under the hood, it uses Chaquopy to package the Python application into an Android app and to bind to the Android Java APIs. Additionally, a GUI using the Toga library is required for requesting Bluetooth permissions.
The BeeWare backend classes are located in the bleak.backends.android package and are
automatically selected when the application is built with Briefcase.
This backend requires Python 3.13 or later, as Android is only officially supported since that
version (see PEP 738) and only since then can an Android
environment be reliably detected via sys.platform == "android" at runtime or via
environment markers
(sys_platform == "android") for dependency resolution.
Briefcase Configuration
To use Bluetooth functionality in an application built with Briefcase, some settings must be
configured in the pyproject.toml file.
Static proxies must be defined so that Java callbacks from Android can be forwarded to the Python implementations in Bleak:
build_gradle_extra_content = """
android.defaultConfig.python.staticProxy(
'bleak.backends.android.scanner_callback',
'bleak.backends.android.client_callback',
'bleak.backends.android.broadcast'
)
"""
Additionally, the required Bluetooth permissions must be added. Briefcase has an option to add Bluetooth permissions to the app (available since Briefcase v0.3.26):
permission.bluetooth = "This app uses Bluetooth to communicate with nearby Bluetooth devices."
This will automatically add the Bluetooth permissions to the application’s AndroidManifest.xml.
But this only means that the app can request Bluetooth permissions, not that the app automatically
has them. The app must still check for and request the permissions at runtime from the user. This is
done automatically by Bleak when the BleakScanner or BleakClient is used for the first time.
If the app does not yet have Bluetooth permission, it will be automatically requested via a popup dialog
by the Android OS:
For an example of building an Android Bluetooth app using BeeWare, see the briefcase testbed.
Backend Specific Quirks
On Android, no more than 5 start/stop scanning operations are allowed per 30 seconds! See also
this issue comment or
this PR in the Android OS.
Before Android 13 (API level 33), if this limit is exceeded, scanning simply won’t work without
producing an error. Therefore, Bleak tracks the start times of scans itself and raises a
BleakError when starting a scan would exceed the limit. The error message includes the time
to wait before scanning is possible again.
BleakAdapter.get_connected_devices() can only filter by service UUIDs of devices for
which Android has already performed GATT service discovery (e.g. devices that were connected
with BleakClient before). Devices connected by other apps may not be found.
API
Scanner
- class bleak.backends.android.scanner.BleakScannerAndroid(detection_callback: Callable[[BLEDevice, AdvertisementData], Coroutine[Any, Any, None] | None] | None, service_uuids: list[str] | None, scanning_mode: Literal['active', 'passive'], **kwargs: Any)[source]
Android Bleak BLE Scanner using Chaquopy/BeeWare.
- Parameters:
detection_callback – Optional function that will be called each time a device is discovered or advertising data has changed.
service_uuids – Optional list of service UUIDs to filter on. Only advertisements containing this advertising data will be received. Specifying this also enables scanning while the screen is off on Android.
scanning_mode – Set to
"passive"to avoid the"active"scanning mode.
- class bleak.backends.android.scanner.ExcessiveUsageChecker[source]
On Android, no more than 5 start/stop scanning operations are allowed per 30 seconds!
Before API level 33, Android does not report an error when this limit is exceeded, scanning just silently doesn’t work. This is a helper class to track scan start times so that we can raise an error instead.
See this commit: https://android-review.googlesource.com/c/platform/packages/apps/Bluetooth/+/215844 Or this comment: https://github.com/NordicSemiconductor/Android-Scanner-Compat-Library/issues/18#issuecomment-402412139
Client
- class bleak.backends.android.client.BleakClientAndroid(address_or_ble_device: BLEDevice | str, services: set[UUID] | None, *, disconnected_callback: Callable[[], None] | None, timeout: float, **kwargs: Any)[source]
Android Bleak Client using Chaquopy/BeeWare.
- Parameters:
address_or_ble_device – The Bluetooth address of the BLE peripheral to connect to or the
BLEDeviceobject representing it.services – Optional set of services UUIDs to filter.
- property is_connected: bool
Check connection status between this client and the server.
- Returns:
Boolean representing connection status.
- property mtu_size: int
Gets the negotiated MTU.
- property name: str
- async read_gatt_char(characteristic: BleakGATTCharacteristic, *, use_cached: bool = False, **kwargs: Any) bytearray[source]
Perform read operation on the specified GATT characteristic.
- Parameters:
characteristic (BleakGATTCharacteristic) – The characteristic to read from.
- Returns:
(bytearray) The read data.
- async read_gatt_descriptor(descriptor: BleakGATTDescriptor, *, use_cached: bool = False, **kwargs: Any) bytearray[source]
Perform read operation on the specified GATT descriptor.
- Parameters:
descriptor – The descriptor to read from.
use_cached – Whether to use cached value.
- Returns:
The read data.
- async start_notify(characteristic: BleakGATTCharacteristic, callback: Callable[[bytearray], None], **kwargs: Any) None[source]
Activate notifications/indications on a characteristic.
- async stop_notify(characteristic: BleakGATTCharacteristic) None[source]
Deactivate notification/indication on a specified characteristic.
- Parameters:
characteristic (BleakGATTCharacteristic) – The characteristic to deactivate notification/indication on,.
- async write_gatt_char(characteristic: BleakGATTCharacteristic, data: SizedBuffer, response: bool) None[source]
Perform a write operation on the specified GATT characteristic.
- Parameters:
characteristic – The characteristic to write to.
data – The data to send.
response – If write-with-response operation should be done.
- async write_gatt_descriptor(descriptor: BleakGATTDescriptor, data: SizedBuffer) None[source]
Perform a write operation on the specified GATT descriptor.
- Parameters:
data (bytes or bytearray) – The data to send.
Adapter
- class bleak.backends.android.adapter.BleakAdapterAndroid(manager: android.bluetooth.BluetoothManager)[source]
The Android Bleak BLE Adapter using Chaquopy/BeeWare.
- async classmethod get(**kwargs: Any) Self[source]
Get a Bluetooth adapter for the current platform.
- Returns:
A platform-specific
BaseBleakAdapterinstance.- Raises:
NotImplementedError – if the current backend does not support this.
- async get_connected_devices(service_uuids: frozenset[str]) list[BLEDevice][source]
Retrieve BLE devices that are currently connected to the system.
- Parameters:
service_uuids – Service UUIDs to filter on.
- Returns:
A list of
BLEDevicefor each connected BLE device.- Raises:
NotImplementedError – if the current backend does not support this.