Skip to content

Commit

Permalink
add permissions request method
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomasz Duda committed Oct 17, 2024
1 parent 8073b41 commit 54fa209
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Changed
* Don't change ctypes' global state ``bleak.backends.winrt.util``.
* Improved performance of BlueZ backend when there are many adapters.
* Added support for Python 3.13.
* **BREAKING CHANGE** Android backend do not request permissions in background. ``request_permissions()`` has to be called explicitly.

`0.22.2`_ (2024-06-01)
======================
Expand Down
1 change: 1 addition & 0 deletions bleak/backends/p4android/defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
BLEAK_JNI_NAMESPACE + ".PythonBluetoothGattCallback"
)

VERSION = autoclass('android.os.Build$VERSION')

class ScanFailed(enum.IntEnum):
ALREADY_STARTED = ScanCallback.SCAN_FAILED_ALREADY_STARTED
Expand Down
25 changes: 0 additions & 25 deletions bleak/backends/p4android/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from asyncio import timeout as async_timeout

from android.broadcast import BroadcastReceiver
from android.permissions import Permission, request_permissions
from jnius import cast, java_method

from ...exc import BleakError
Expand Down Expand Up @@ -73,30 +72,6 @@ async def start(self) -> None:
if self.__callback is None:
self.__callback = _PythonScanCallback(self, loop)

permission_acknowledged = loop.create_future()

def handle_permissions(permissions, grantResults):
if any(grantResults):
loop.call_soon_threadsafe(
permission_acknowledged.set_result, grantResults
)
else:
loop.call_soon_threadsafe(
permission_acknowledged.set_exception(
BleakError("User denied access to " + str(permissions))
)
)

request_permissions(
[
Permission.ACCESS_FINE_LOCATION,
Permission.ACCESS_COARSE_LOCATION,
"android.permission.ACCESS_BACKGROUND_LOCATION",
],
handle_permissions,
)
await permission_acknowledged

self.__adapter = defs.BluetoothAdapter.getDefaultAdapter()
if self.__adapter is None:
raise BleakError("Bluetooth is not supported on this hardware platform")
Expand Down
35 changes: 35 additions & 0 deletions bleak/backends/p4android/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
import asyncio
import logging
import warnings
from typing import List, Optional

from android.permissions import Permission
from android.permissions import request_permissions as request_android_permissions
from jnius import PythonJavaClass

from ...exc import BleakError
from . import defs

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -92,3 +96,34 @@ def _result_state_unthreadsafe(self, failure_str, source, data):
else:
# send it on the event thread
raise exception

async def request_permissions(permissions: Optional[List[str]] = None) -> None:
loop = asyncio.get_running_loop()
permission_acknowledged = loop.create_future()
def handle_permissions(permissions, grantResults):
if any(grantResults):
loop.call_soon_threadsafe(
permission_acknowledged.set_result, grantResults
)
else:
loop.call_soon_threadsafe(
permission_acknowledged.set_exception(
BleakError("User denied access to " + str(permissions))
)
)
if permissions is None:
permissions = [
Permission.ACCESS_FINE_LOCATION,
Permission.ACCESS_COARSE_LOCATION,
Permission.ACCESS_BACKGROUND_LOCATION,
]
if defs.VERSION.SDK_INT >= 31:
permissions.extend([
Permission.BLUETOOTH_SCAN,
Permission.BLUETOOTH_CONNECT,
])
request_android_permissions(
permissions,
handle_permissions,
)
await permission_acknowledged
4 changes: 4 additions & 0 deletions examples/kivy/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import os

import bleak
from kivy.app import App
Expand Down Expand Up @@ -38,6 +39,9 @@ def on_stop(self):
self.running = False

async def example(self):
if os.environ.get("P4A_BOOTSTRAP") is not None:
from bleak.backends.p4android.utils import request_permissions
await request_permissions()
while self.running:
try:
self.line("scanning")
Expand Down

0 comments on commit 54fa209

Please sign in to comment.