Baseflow / Baseflow/flutter-permission-handler
flutter: Bluetooth permissions denied. Scan: false, Connect: false
- Dominant language
- Dart
- Stars
- 2.2k
- Forks
- 970
- Avg merge
- 14h 22m
- Merged PRs (30d)
- 2
Description
### Please check the following before submitting a new issue.
- [X] I have searched the [existing issues](https://github.com/baseflow/flutter-permission-handler/issues).
- [X] I have carefully [read the documentation](https://github.com/baseflow/flutter-permission-handler/blob/main/permission_handler/README.md).
### Please select for which platform(s) you need help
- [ ] Android
- [X] iOS
- [ ] Windows
### Your question
I am developing a bluetooth scanning app using flutter and I encountered permission issue.
I get this message when I try to test it.
flutter: Bluetooth permissions denied. Scan: false, Connect: false
This is my main.dart
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter BLE Scanner',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class BleController extends GetxController {
FlutterBlue ble = FlutterBlue.instance;
List devicesList = []; // To store discovered devices
// This function will start the BLE scan and update the device list
Future scanDevices() async {
var bluetoothScanPermission = await Permission.bluetoothScan.request();
var bluetoothConnectPermission = await Permission.bluetoothConnect.request();
// Check if both Bluetooth scan and connect permissions are granted
if (bluetoothScanPermission.isGranted && bluetoothConnectPermission.isGranted) {
// Start scanning
ble.startScan(timeout: Duration(seconds: 15));
// Listen to scan results and add them to the list
ble.scanResults.listen((results) {
devicesList = results;
update(); // Notify listeners to rebuild the UI with the updated devices list
});
// Stop scanning after the timeout
await Future.delayed(Duration(seconds: 15));
ble.stopScan();
} else {
print("Bluetooth permissions denied. Scan: ${bluetoothScanPermission.isGranted}, Connect: ${bluetoothConnectPermission.isGranted}");
}
}
// Function to connect to a device
Future connectToDevice(BluetoothDevice device) async {
try {
await device.connect(timeout: Duration(seconds: 15));
device.state.listen((state) {
if (state == BluetoothDeviceState.connecting) {
print("Connecting to ${device.name}...");
} else if (state == BluetoothDeviceState.connected) {
print("Connected to ${device.name}");
} else {
print("Device ${device.name} disconnected");
}
});
} catch (e) {
print("Error connecting to device: $e");
}
}
// Stream to listen for scan results
Stream> get scanResults => ble.scanResults;
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("BLE Scanner"),
),
body: GetBuilder(
init: BleController(),
builder: (controller) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// List the found devices
Expanded(
child: ListView.builder(
itemCount: controller.devicesList.length,
itemBuilder: (context, index) {
final device = controller.devicesList[index];
return Card(
elevation: 2,
child: ListTile(
title: Text(device.device.name.isNotEmpty
? device.device.name
: "Unnamed Device"),
subtitle: Text(device.device.id.id),
trailing: Text(device.rssi.toString()),
onTap: () => controller.connectToDevice(device.device),
),
);
},
),
),
SizedBox(height: 10),
// Button to start scanning
ElevatedButton(
onPressed: () async {
await controller.scanDevices();
},
child: const Text("Start Scan"),
),
],
),
);
},
),
);
}
}
This is my info.plist
CADisableMinimumFrameDurationOnPhone
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
NSBluetoothAlwaysUsageDescription
We need access to Bluetooth to scan and connect to nearby devices.
NSBluetoothPeripheralUsageDescription
We need access to Bluetooth to communicate with nearby devices.
CFBundleDisplayName
Testflutter
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
testflutter
CFBundlePackageType
APPL
CFBundleShortVersionString
$(FLUTTER_BUILD_NAME)
CFBundleSignature
????
CFBundleVersion
$(FLUTTER_BUILD_NUMBER)
LSRequiresIPhoneOS
UIApplicationSupportsIndirectInputEvents
UILaunchStoryboardName
LaunchScreen
UIMainStoryboardFile
Main
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
UISupportedInterfaceOrientations~ipad
UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
This is my pod file
# Uncomment this line to define a global platform for your project
platform :ios, '12.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
# Add Bluetooth permission for iOS
post_install do |installer|
installer.pods_project.targets.each do |target|
# Add the Bluetooth permission to the build settings
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
'PERMISSION_BLUETOOTH=1', # Add this line for Bluetooth permission
]
end
flutter_additional_ios_build_settings(target)
end
end
end

Eventhough the app asks for permission and even after granting it, it says that flutter: Bluetooth permissions denied. Can someone help?
### Version
na
Contributor guide
Assessment
This issue has not been assessed yet.