Bluetooth Low Energy (BLE) device scanning, connection, and GATT operations for WebF applications
Version 1.0.0
Scan for nearby BLE devices with optional service UUID filters and configurable timeout.
Connect and disconnect from BLE devices with timeout configuration and MTU negotiation support.
Discover services, characteristics, and descriptors on connected devices with full GATT support.
Subscribe to characteristic notifications and receive real-time value updates from BLE devices.
1dependencies:
2 webf_bluetooth: ^1.0.01import 'package:webf/webf.dart';
2import 'package:webf_bluetooth/webf_bluetooth.dart';
3
4void main() {
5 // Register module globally
6 WebF.defineModule((context) => BluetoothModule(context));
7 runApp(MyApp());
8}1npm install @openwebf/webf-bluetooth1import { useEffect, useState } from 'react';
2import { WebFBluetooth, BluetoothScanResultPayload } from '@openwebf/webf-bluetooth';
3
4export function BluetoothScanner() {
5 const [devices, setDevices] = useState<BluetoothScanResultPayload[]>([]);
6 const [isScanning, setIsScanning] = useState(false);
7
8 useEffect(() => {
9 // Listen for scan results
10 const unsubscribe = WebFBluetooth.addListener('scanResult', (_event, device) => {
11 setDevices(prev => {
12 const existing = prev.find(d => d.deviceId === device.deviceId);
13 if (existing) {
14 return prev.map(d => d.deviceId === device.deviceId ? device : d);
15 }
16 return [...prev, device];
17 });
18 });
19
20 return () => unsubscribe();
21 }, []);
22
23 const startScan = async () => {
24 setDevices([]);
25 const result = await WebFBluetooth.startScan({ timeout: 10000 });
26 if (result.success === 'true') {
27 setIsScanning(true);
28 setTimeout(() => setIsScanning(false), 10000);
29 }
30 };
31
32 return (
33 <div>
34 <button onClick={startScan} disabled={isScanning}>
35 {isScanning ? 'Scanning...' : 'Start Scan'}
36 </button>
37 {devices.map(device => (
38 <div key={device.deviceId}>
39 {device.name || 'Unknown'} ({device.rssi} dBm)
40 </div>
41 ))}
42 </div>
43 );
44}1import { WebFBluetooth } from '@openwebf/webf-bluetooth';
2
3// Connect to a device
4const connectResult = await WebFBluetooth.connect({
5 deviceId: 'AA:BB:CC:DD:EE:FF',
6 timeout: 15000,
7 autoConnect: false,
8});
9
10if (connectResult.success === 'true') {
11 console.log('Connected! MTU:', connectResult.mtu);
12
13 // Discover services
14 const servicesResult = await WebFBluetooth.discoverServices('AA:BB:CC:DD:EE:FF');
15
16 if (servicesResult.success === 'true') {
17 const services = JSON.parse(servicesResult.services!);
18
19 services.forEach(service => {
20 console.log(`Service: ${service.uuid}`);
21 service.characteristics.forEach(char => {
22 console.log(` Characteristic: ${char.uuid}`);
23 console.log(` Properties:`, char.properties);
24 });
25 });
26 }
27}1import { WebFBluetooth } from '@openwebf/webf-bluetooth';
2
3// Read a characteristic
4const readResult = await WebFBluetooth.readCharacteristic({
5 deviceId: 'AA:BB:CC:DD:EE:FF',
6 serviceUuid: '180D', // Heart Rate service
7 characteristicUuid: '2A37',
8});
9
10if (readResult.success === 'true') {
11 console.log('Value (hex):', readResult.value);
12 console.log('Value (base64):', readResult.valueBase64);
13}
14
15// Write to a characteristic
16const writeResult = await WebFBluetooth.writeCharacteristic({
17 deviceId: 'AA:BB:CC:DD:EE:FF',
18 serviceUuid: 'custom-service-uuid',
19 characteristicUuid: 'custom-char-uuid',
20 value: '0102030405', // hex string
21 withoutResponse: false,
22});
23
24if (writeResult.success === 'true') {
25 console.log('Write successful');
26}1import { WebFBluetooth } from '@openwebf/webf-bluetooth';
2
3// Listen for notifications
4WebFBluetooth.addListener('notification', (_event, detail) => {
5 const { characteristicUuid, value, valueBase64 } = detail;
6 console.log(`Notification from ${characteristicUuid}: ${value}`);
7});
8
9// Subscribe to Heart Rate Measurement
10const subResult = await WebFBluetooth.subscribeToNotifications({
11 deviceId: 'AA:BB:CC:DD:EE:FF',
12 serviceUuid: '180D',
13 characteristicUuid: '2A37',
14});
15
16if (subResult.success === 'true') {
17 console.log('Subscribed! ID:', subResult.subscriptionId);
18}
19
20// Unsubscribe when done
21await WebFBluetooth.unsubscribeFromNotifications(subResult.subscriptionId);1import { WebFBluetooth } from '@openwebf/webf-bluetooth';
2
3// Listen for connection state changes
4WebFBluetooth.addListener('connectionState', (_event, detail) => {
5 console.log(`Device ${detail.deviceId}: ${detail.state}`);
6 // state can be: 'disconnected', 'connecting', 'connected', 'disconnecting'
7});
8
9// Check adapter state
10const stateResult = await WebFBluetooth.getAdapterState();
11console.log('Adapter state:', stateResult.state);
12// state can be: 'on', 'off', 'turningOn', 'turningOff', 'unavailable'
13
14// Get connected devices
15const devicesResult = await WebFBluetooth.getConnectedDevices();
16const devices = JSON.parse(devicesResult.devices!);
17console.log('Connected devices:', devices);getAdapterState()Get current Bluetooth adapter stateisBluetoothOn()Check if Bluetooth is enabledturnOn()Turn on Bluetooth (Android only)startScan(options?)Start scanning for BLE devicesstopScan()Stop active scanisScanning()Check if currently scanningconnect(options)Connect to a BLE devicedisconnect(deviceId)Disconnect from a devicegetConnectionState(deviceId)Get connection stategetConnectedDevices()List connected devicesrequestMtu(deviceId, mtu)Request MTU size (Android)discoverServices(deviceId)Discover services and characteristicsreadCharacteristic(options)Read characteristic valuewriteCharacteristic(options)Write to characteristicreadDescriptor(options)Read descriptor valuewriteDescriptor(options)Write to descriptorsubscribeToNotifications(options)Subscribe to characteristic notificationsunsubscribeFromNotifications(id)Unsubscribe from notificationsscanResultEmitted for each device found during scanningconnectionStateEmitted when connection state changesnotificationEmitted when subscribed characteristic value changesAdd the following permissions to your AndroidManifest.xml:
1<uses-permission android:name="android.permission.BLUETOOTH" />
2<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
3<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
4<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
5<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />Add the following keys to your Info.plist:
1<key>NSBluetoothAlwaysUsageDescription</key>
2<string>This app uses Bluetooth to connect to BLE devices.</string>
3<key>NSBluetoothPeripheralUsageDescription</key>
4<string>This app uses Bluetooth to connect to BLE devices.</string>This WebF plugin is built on top of the popular flutter_blue_plus Flutter package, which provides comprehensive Bluetooth Low Energy support for Flutter applications. It is one of the most widely used BLE solutions in the Flutter ecosystem.