PhilipsHue / flutter_reactive_ble

Flutter library that handles BLE operations for multiple devices.
https://developers.meethue.com/
Other
662 stars 326 forks source link

Pixel 4 - Android 12 - Location Permission missing (code 3) when trying to do scan #552

Closed ASHBAW closed 2 years ago

ASHBAW commented 2 years ago

I have a Pixel 4 running Android 12 (API 31).

I create a new simple project to scan for BLE devices. I have the following in the AndroidManifet.xml, though I do not think I would need these with API 31.

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

I use the permission_handler package to have the app determine/allow location permission.

My code is as follows:

  void scanForDevices() {
    flutterReactiveBle.scanForDevices(
      withServices: [_serviceUuid],
      requireLocationServicesEnabled: false,
    ).listen((device) {
      print('device ' + device.name);
    }, onError: (Object e) => print('Device scan fails with error: $e'));
  }

  ElevatedButton(
      onPressed: () async {
        // currently just print out if location services are enabled
        if (await Permission.location.serviceStatus.isEnabled) {
          print('Location services is enabled');
        } else {
          print('Location services is NOT enabled');
        }

        var status = await Permission.location.status;

        if (status.isGranted) {
          print('Location permission is granted');
          scanForDevices();
        } else {
            print('Location permission is not granted');
                await [
                  Permission.location,
                ].request();

                status = await Permission.location.status;

                print(status.isGranted);

                scanForDevices();
        }
      },
      child: const Text('Start Scan'),
      style: ElevatedButton.styleFrom(
        minimumSize: const Size.fromHeight(50), 
      ),
    ),

When I launch the app the following occurs:

  1. select - Start Scan button
  2. print - Location services is enabled - occurs
  3. print - Location permission is not granted - occurs (else statement)
  4. using - permission_handler - request location permissions
  5. pop-up -Allow test to access this device's location? - occurs
  6. select - While using the app
  7. print - status.isGranted - is TRUE
  8. call scanForDevices()
  9. Get following error - Device scan fails with error: Exception: GenericFailure(code: ScanFailure.unknown, message: "Location Permission missing (code 3)")

If I use an older device - Motorola - moto e6 running Android 9 everything works fine. All the steps 1 through 7 occur the same as with the Pixel 4 except no errors like in step 9.

mrRedSun commented 2 years ago

https://developer.android.com/guide/topics/connectivity/bluetooth/permissions

ASHBAW commented 2 years ago

Thanks for the response. I use the provided sample code:

https://github.com/PhilipsHue/flutter_reactive_ble/tree/master/example

modified the android\app\src\main\AndroidManifest.xml with the following permissions:


 <!-- Request legacy Bluetooth permissions on older devices. -->
    <uses-permission android:name="android.permission.BLUETOOTH"
                     android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
                     android:maxSdkVersion="30" />

    <!-- Needed only if your app looks for Bluetooth devices.
         If your app doesn't use Bluetooth scan results to derive physical
         location information, you can strongly assert that your app
         doesn't derive physical location. -->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"
                     android:usesPermissionFlags="neverForLocation" />

    <!-- Needed only if your app makes the device discoverable to Bluetooth
         devices. -->
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />

    <!-- Needed only if your app communicates with already-paired Bluetooth
         devices. -->
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

    <!-- Needed only if your app uses Bluetooth scan results to derive physical location. -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

I also added permission_handler to have the application grant permissions.

The older Motorola device works great. I can scan, connect, etc. The Pixel 4 with Android 12 never returns anything from the scan in the provided sample code.

Any other thoughts on what might be going on?

jobfeikens commented 2 years ago

I think on Android 12 you need to request the BLUETOOTH_SCAN permission: await Permission.bluetoothScan.request() (and BLUETOOTH_CONNECT if you want to connect). After this, you don't need to request location permission.

gourav6m17 commented 2 years ago

Hi @jobfeikens, have your problem solved after this, because my problem is not solved yet. Everytime is says add android.permission.BLUETOOTH_SCAN after adding this and await Permission.bluetoothScan.request() this too always same problem. I'm trying it on Samsung 20FE.

jobfeikens commented 2 years ago

Yes, did you add permissions to AndroidManifest.xml like ASHBAW above? Also try deleting your app from your phone as that seems to refresh permission changes. I'm using a google pixel 5, maybe there are some differences?

ASHBAW commented 2 years ago

Thanks jobfeikens!

I also added permission requests for bluetoothConnect and bluetoothAdvertise and it is now working on my Pixel 4 running Android 12.

robin-glimp commented 2 years ago

Something I encountered here: make sure you have the targetSdkVersion specified in your android/app/build.gradle file to be 31 or higher.

For this to work with your app you might need to add some other metadata in the AndroidManifest.xml, namely: android:exported on the relevant fields (see https://cafonsomota.medium.com/android-12-dont-forget-to-set-android-exported-on-your-activities-services-and-receivers-3bee33f37beb)

Taym95 commented 2 years ago

Please follow the instructing in readme.

Kamal3113 commented 7 months ago

kindly , add this permission check before scan: await Permission.bluetoothConnect.request().isGranted;

this will help in each and every (Android Version).

farr64 commented 7 months ago

kindly , add this permission check before scan: await Permission.bluetoothConnect.request().isGranted;

this will help in each and every (Android Version).

Where and how? Do I need to add something else (somewhere specific) as a prerequisite?

If I simply add your suggested code before scanning, it produces an error: Undefined name 'Permission'.

Thanks.

Taym95 commented 7 months ago

kindly , add this permission check before scan: await Permission.bluetoothConnect.request().isGranted; this will help in each and every (Android Version).

Where and how? Do I need to add something else (somewhere specific) as a prerequisite?

If I simply add your suggested code before scanning, it produces an error: Undefined name 'Permission'.

Thanks.

Permission is package, so you need to add permission_handler to your dependency

farr64 commented 7 months ago

Thanks for the tip, @Taym95. That explains everything.