Skip to Content

Bluetooth Plugin

Bluetooth Low Energy (BLE) device scanning, connection, and GATT operations for WebF applications

Version 1.0.0

Features

Device Scanning

Scan for nearby BLE devices with optional service UUID filters and configurable timeout.

Connection Management

Connect and disconnect from BLE devices with timeout configuration and MTU negotiation support.

Service Discovery

Discover services, characteristics, and descriptors on connected devices with full GATT support.

Real-time Notifications

Subscribe to characteristic notifications and receive real-time value updates from BLE devices.

Installation

1. Add to pubspec.yaml

pubspec.yaml
1dependencies:
2  webf_bluetooth: ^1.0.0

2. Register the module

main.dart
1import '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}

3. Install npm package (JavaScript/TypeScript)

1npm install @openwebf/webf-bluetooth

Usage Examples

Basic Scanning

BluetoothScanner.tsx
1import { 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}

Connect & Discover Services

connect.ts
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}

Read & Write Characteristics

characteristic-ops.ts
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}

Subscribe to Notifications

notifications.ts
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);

Monitor Connection State

connection-state.ts
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);

API Reference

Adapter Management

getAdapterState()Get current Bluetooth adapter state
isBluetoothOn()Check if Bluetooth is enabled
turnOn()Turn on Bluetooth (Android only)

Scanning

startScan(options?)Start scanning for BLE devices
stopScan()Stop active scan
isScanning()Check if currently scanning

Connection Management

connect(options)Connect to a BLE device
disconnect(deviceId)Disconnect from a device
getConnectionState(deviceId)Get connection state
getConnectedDevices()List connected devices
requestMtu(deviceId, mtu)Request MTU size (Android)

Service Discovery

discoverServices(deviceId)Discover services and characteristics

Data Transfer

readCharacteristic(options)Read characteristic value
writeCharacteristic(options)Write to characteristic
readDescriptor(options)Read descriptor value
writeDescriptor(options)Write to descriptor

Notifications

subscribeToNotifications(options)Subscribe to characteristic notifications
unsubscribeFromNotifications(id)Unsubscribe from notifications

Events

scanResultEmitted for each device found during scanning
connectionStateEmitted when connection state changes
notificationEmitted when subscribed characteristic value changes

Platform Notes

Android

Add the following permissions to your AndroidManifest.xml:

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" />

iOS / macOS

Add the following keys to your Info.plist:

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>

Limitations

  • BLE Central Role only - This plugin supports scanning and connecting to peripherals. It does not support acting as a BLE peripheral.
  • No Bluetooth Classic - Devices using Bluetooth Classic (HC-05, speakers, headphones, mice, keyboards) are not supported.
  • No iBeacon on iOS - iBeacons require CoreLocation on iOS.

Based On

Flutter

flutter_blue_plus

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.