flutter-permission-handler icon indicating copy to clipboard operation
flutter-permission-handler copied to clipboard

[Bug]: Bluetooth permission on iOS permanently denied

Open lazarvgd opened this issue 1 year ago • 17 comments

Please check the following before submitting a new issue.

Please select affected platform(s)

  • [ ] Android
  • [X] iOS
  • [ ] Windows

Steps to reproduce

  1. add the dependency to pubspec.yaml
  2. add permission for BT in info.plist
  3. update podfile with the following code:
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
              '$(inherited)',

              ## dart: PermissionGroup.bluetooth
              'PERMISSION_BLUETOOTH=1',

            ]
  1. request permission in the code as following:
  @override
  Future<bool> getBluetoothPermission() async {
   final PermissionStatus  status = await Permission.bluetoothConnect.request();
    return status == PermissionStatus.granted;
  }

Expected results

When the bt is enabled in Settings-> <app_name> -> Bluetooth, result of the code should be "granted", when it is disabled it should be some variant of denied.

Actual results

The actual result is that the code always return permanentlyDenied.

Code sample

Code sample
  @override
  Future<bool> getBluetoothPermission() async {
   final PermissionStatus  status = await Permission.bluetoothConnect.request();
    return status == PermissionStatus.granted;
  }

Screenshots or video

Screenshots or video demonstration

image Screenshot 2024-06-10 at 10 21 53

Version

11.3.1

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.22.1, on macOS 14.5 23F79 darwin-arm64, locale en-GB)
    • Flutter version 3.22.1 on channel stable at /Users/lj/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision a14f74ff3a (3 weeks ago), 2024-05-22 11:08:21 -0500
    • Engine revision 55eae6864b
    • Dart version 3.4.1
    • DevTools version 2.34.3

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/lj/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11572160)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15F31d
    • CocoaPods version 1.15.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2023.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11572160)

[✓] VS Code (version 1.89.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.88.0

[✓] Connected device (5 available)
    • SM S911B (mobile)               • RFCW202MYCV               • android-arm64  • Android 14 (API 34)
    • iPhone-J1HPW2QJMW (mobile)      • 00008110-001E14E90E3A401E • ios            • iOS 17.5.1 21F90
    • macOS (desktop)                 • macos                     • darwin-arm64   • macOS 14.5 23F79 darwin-arm64
    • Mac Designed for iPad (desktop) • mac-designed-for-ipad     • darwin         • macOS 14.5 23F79 darwin-arm64
    • Chrome (web)                    • chrome                    • web-javascript • Google Chrome 125.0.6422.142

[✓] Network resources
    • All expected network resources are available.

• No issues found!

Tested on iOS 17.5.1, iphone 14.

lazarvgd avatar Jun 10 '24 08:06 lazarvgd

I too had this issue.

The problem in my case was, that I had not run pod install after modifying podfile.

Solution: reinstall the pod.

  1. Move to ios folder cd ios
  2. Run the command pod install.

this solved my issue.

ritheshSalyan avatar Jun 12 '24 10:06 ritheshSalyan

The proposed solution does not work.

lazarvgd avatar Jun 20 '24 05:06 lazarvgd

Dear @lazarvgd,

Does this also happen while you test this in the Example app?

Kins regards,

TimHoogstrate avatar Jun 28 '24 07:06 TimHoogstrate

I have encountered the same problem.Sorry, I am not good at iOS compilation and the Example app cannot be compiled successfully. Tested on iOS 16.7.7, iphone 8.

tilongzs avatar Jul 02 '24 04:07 tilongzs

Specific App Settings Permission image

this bluetooth permission request returns permanentlyDenied status

      var status1 = await Permission.bluetooth.request();

In fact Permission is granted, I can scan nearby bluetooth devices!

And the example app return a 'Granted' answer: image


It seems related to our own project...

So I tried to put the project reference in pubspec.yaml

  permission_handler:
    path: ../../flutter-permission-handler/permission_handler

I still got a permanentlyDenied status for my application, and it does not stop on breakpoint in file flutter-permission-handler/permission_handler/lib/permission_handler.dart

If you have any advice to debug this? let me know.

Phenek avatar Jul 10 '24 10:07 Phenek

I have encountered the same problem.Sorry, I am not good at iOS compilation and the Example app cannot be compiled successfully. Tested on iOS 16.7.7, iphone 8.

The example project compiles correctly.

@Phenek,

Please file a separate issue. Also check the correct plist entries and the pod file entries. Then run flutter build ios.

Kind regards,

TimHoogstrate avatar Aug 05 '24 06:08 TimHoogstrate

same issue for me - spent already many hrs on this but still fail to solve the issue. A always get Permission.denied when in fact on the devise the permission is granted.

Any updates on this? Flutter 3.22.2 iOS 17.6

fufylev avatar Aug 07 '24 05:08 fufylev

Dear @fufylev,

Please file a separate issue. And follow the instructions in the README. You probably forgot to update the podfile or the plist entries.

Kind regards,

TimHoogstrate avatar Aug 07 '24 07:08 TimHoogstrate

@fufylev
When I have granted permission on the app, why does it still show as permanentlyDenied? Is there any way to fix it? image

image

permission_handler: ^11.3.1

Hoai-Phong avatar Aug 20 '24 02:08 Hoai-Phong

Same issue on ios18 , flutter 3.22.2 with notifications permission

sahharYoucef avatar Sep 28 '24 09:09 sahharYoucef

I'm facing the same issue !

djamel96 avatar Oct 03 '24 14:10 djamel96

Faced same issue with notifications permission on iOS devices, flutter 3.22.4. It always returned permanentlyDenied no matter what I do. Podfile and Info.plist is set up according to readme.

I my case, I had this additional line in my Podfile:

flutter_additional_ios_build_settings(target)

and it was placed at the end of installer.pods_project.targets.each do |target|, after permission macros:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        ## dart: PermissionGroup.notification
        'PERMISSION_NOTIFICATIONS=1',
      ]

    end
    flutter_additional_ios_build_settings(target)
  end
end

I moved it to the beginning and it resolved my issue:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    target.build_configurations.each do |config|
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        ## dart: PermissionGroup.notification
        'PERMISSION_NOTIFICATIONS=1',
      ]

    end
  end
end

maxindieflow avatar Nov 26 '24 07:11 maxindieflow

Hey everyone. I am also encountering this issue. Here let me share screenshots:

I have modified my Podfile with the appropriate macros accordingly

Screenshot 2024-12-12 at 6 49 05 PM

I have added appropriate descriptions in Info.plist

<key>NSBluetoothPeripheralUsageDescription</key>
<string>...</string>
<key>NSBluetoothAlwaysUsageDescription</key>
<string>...</string>

Here are the relevant contents of my pubspec.yaml and pubspec.lock files

pubspec.yaml Screenshot 2024-12-12 at 7 04 16 PM

pubspec.lock Screenshot 2024-12-12 at 7 03 56 PM

Now I run my app. It actually asks for bluetooth permission and i grant it

https://github.com/user-attachments/assets/ebd5c05a-692b-4b5b-b753-6bd07c98daf0

https://github.com/user-attachments/assets/a760b409-675b-4a8f-bd3f-f1d7def836fb

You can clearly see that bluetooth permission is granted here IMG_1842

So why does this still happen? Screenshot 2024-12-12 at 7 17 03 PM

Daeon97 avatar Dec 12 '24 18:12 Daeon97

Okay so I have fixed this by eliminating the line if target.name == "geolocator_apple" and including a new line and the comment ## dart: PermissionGroup.bluetooth just before the line 'PERMISSION_BLUETOOTH=1',

Screenshot 2024-12-12 at 8 42 00 PM

Specifically instead of

if target.name == "geolocator_apple"
  target.build_configurations.each do |config|
    config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
      '$(inherited)',
      'PERMISSION_BLUETOOTH=1',
    ]
  end
end

I now have

target.build_configurations.each do |config|
  config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
    '$(inherited)',

    ## dart: PermissionGroup.bluetooth
    'PERMISSION_BLUETOOTH=1',
  ]
end

Thanks to @demola234 for pointing things out

Daeon97 avatar Dec 12 '24 19:12 Daeon97

Dear @lazarvgd,

Does this also happen while you test this in the Example app?

Kins regards,

I want to apologize for the late reply.

The issue was happening in the example app. I couldn't wait for the fix so I ended writing my own permission handler. I can confirm that the tests above are the same for me.

Cheers

lazarvgd avatar Dec 13 '24 07:12 lazarvgd

My workaround on Bluetooth permission using FlutterBluePlus:

  static Future<BluetoothAdapterState> getFirstBluetoothAdapterState() async {
    final completer = Completer<BluetoothAdapterState>();
    late StreamSubscription<BluetoothAdapterState> subscription;

    subscription = FlutterBluePlus.adapterState.listen((BluetoothAdapterState state) {
      if (state == BluetoothAdapterState.unknown) return;
      
      completer.complete(state);
      subscription.cancel();
    });

    return completer.future;
  }

  static Future<bool> isBluetoothEnabled() async {
    var state = await getFirstBluetoothAdapterState();
    if (state == BluetoothAdapterState.on) {
      if (Platform.isAndroid && !(await Permission.bluetoothScan.isGranted)) {
        showBluetoothUnauthorizedPopup();
        return false;
      }
      return true;
    } else if (state == BluetoothAdapterState.off) {
      showBluetoothDisabledPopup();
      return false;
    } else if (state == BluetoothAdapterState.unauthorized) {
      showBluetoothUnauthorizedPopup();
      return false;
    }
    return false;
  }

Phenek avatar Apr 06 '25 17:04 Phenek