Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android permissions #1621

Open
vascolp opened this issue Jul 22, 2024 · 6 comments
Open

Android permissions #1621

vascolp opened this issue Jul 22, 2024 · 6 comments

Comments

@vascolp
Copy link

vascolp commented Jul 22, 2024

Hello again!

  • bleak version: 0.22.2
  • Python version: python 3.10.12
  • Operating System: Android 14

Description

I have an android app that works very well with bleak (good start :-))
The app does not require location data. It only uses BLE to scan and connect to LEGO Hubs.
But bleak forces permissions ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, ACCESS_BACKGROUND_LOCATION.

Location permitions are a problem if you intend to do an android app that can be used by children.
Android offers the ability to "strongly assert that my app does not use location" (check point 5 here).
According to the same page, I am also convinced that in some situations ACCESS_BACKGROUND_LOCATION is also not needed. My case in particular.

Testing

I tried all this by making a copy of bleak and just commenting the call to the request_permissions() (and following await) and using these buildozer permissions (check the special case for BLUETOOTH_SCAN):

android.permissions = android.permission.INTERNET,android.permission.BLUETOOTH_ADMIN,(name=android.permission.BLUETOOTH_SCAN;usesPermissionFlags=neverForLocation),android.permission.BLUETOOTH_CONNECT

And everything works fine!!

Is there a chance that you could find a way to omit the call to request_permissions() if the user wants that? Some parameter valid only for android, or something like that?

I would appreciate it very much!

Thanks in advance!
VascoLP

@vascolp
Copy link
Author

vascolp commented Jul 26, 2024

Ok, here are some notes about android permission versions, that might be of interest to someone.

  1. Did not investigate versions prior to android 10, but probably it works like android 10.
  2. On android versions 10 and 11, (APIs 29 and 30) bleak will need ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION. In some cases (when there is a background service) you might also need ACCESS_BACKGROUND_LOCATION.
  3. On android 12 and above (API 31 and above), if your app does not use locations, you can use the ability to "strongly assert that my app does not use location" (check it here), so the *LOCATION permissions are not needed.
  4. If you want to give support for android 10 to 14 in a kivy application, and avoid location permissions where possible, you have to give some permissions based on API levels. With the following example, an APP will ask for location permissions in android up to 11, but not on android 12 or above.
    Here is a configuration example.
    Notice that this example will only work if the issue above is fixed. Otherwise, bleak 0.22.2 requests permissions hardcoded.
  5. buildozer.spec:
    # Permissions for APIs 29 to 34. Some of them only for APIs up to 30
    android.permissions = android.permission.INTERNET,android.permission.BLUETOOTH_ADMIN,android.permission.BLUETOOTH_CONNECT,android.permission.BLUETOOTH,(name=android.permission.BLUETOOTH_SCAN;usesPermissionFlags=neverForLocation),(name=android.permission.ACCESS_FINE_LOCATION;maxSdkVersion=30),(name=android.permission.ACCESS_COARSE_LOCATION;maxSdkVersion=30)
    android.api = 34
    android.minapi = 29
  1. Python code to request permissions. You can do it at startup or somewhere where needed with this sample code:
        if platform != 'android': 
            return # or whatever suits you....
        from android import api_version
        from android.permissions import request_permissions, Permission, check_permission
        permissions_list=[
            #Permission.INTERNET,
            Permission.BLUETOOTH_ADMIN,
            Permission.BLUETOOTH_SCAN,
            Permission.BLUETOOTH_CONNECT,
        ]
        if api_version < 31:
            permissions_list.append(Permission.ACCESS_COARSE_LOCATION)
            permissions_list.append(Permission.ACCESS_FINE_LOCATION)
            permissions_list.append(Permission.ACCESS_BACKGROUND_LOCATION) # If needed

        request_permissions(permissions_list)

@dlech
Copy link
Collaborator

dlech commented Jul 26, 2024

I agree that Bleak should not be dealing with Android permissions. It should be up to the individual application to deal with that.

So I would be happy to take a pull request that removes permission stuff from the android backend code and moves it to the example app.

@vascolp
Copy link
Author

vascolp commented Sep 20, 2024

Maybe you could just put the android permissions code inside an if, something like this:

if 'BLEAK_ANDROID_NO_PERMISSIONS' not in globals():
   # get permissions

Then I just would have to define that variable before importing bleak?

@dlech
Copy link
Collaborator

dlech commented Sep 20, 2024

I would rather that it be an explicit function rather than something that happens magically at import.

@vascolp
Copy link
Author

vascolp commented Sep 20, 2024

Well, it would not really be in the import, the if should be inside the BleakScannerP4Android.start() method, and the test would happen in run time.
Well, I would rather have no direct permission handling at all in bleak... but I understand that that might mess with existing apps.

@dlech
Copy link
Collaborator

dlech commented Sep 23, 2024

Given that things are kind of broken anyway on newer android versions, I think it would be OK to make a breaking change in this case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants