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 13, 2024
1 parent 3393c46 commit 9f9f860
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Changed
* In bleak.backends.winrt.util the SetTimer, KillTimer and CoGetApartmentType functions define their own prototype and don't change ctypes' global state anymore
* 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
39 changes: 39 additions & 0 deletions bleak/backends/p4android/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@

from jnius import PythonJavaClass

from android.permissions import Permission
from android.permissions import request_permissions as request_android_permissions
from ...exc import BleakError
from . import defs

from typing import (
List,
Optional,
)

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -92,3 +100,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
Expand Up @@ -8,6 +8,7 @@
# bind bleak's python logger into kivy's logger before importing python module using logging
from kivy.logger import Logger # isort: skip
import logging # isort: skip
import os

logging.Logger.manager.root = Logger

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 9f9f860

Please sign in to comment.