universal_bluetooth 0.0.1 copy "universal_bluetooth: ^0.0.1" to clipboard
universal_bluetooth: ^0.0.1 copied to clipboard

A universal Bluetooth plugin for Flutter supporting Classic Bluetooth, BLE, and iBeacon.

Universal Bluetooth Plugin for Flutter #

A comprehensive Flutter plugin that provides unified access to Classic Bluetooth, Bluetooth Low Energy (BLE), and iBeacon functionality across iOS and Android platforms.

corp : https://jamkrafters.com

🚀 Features #

✅ Classic Bluetooth #

  • Device scanning and discovery
  • Connection management (pairing/disconnection)
  • Bidirectional data communication
  • Connection state monitoring
  • Make device discoverable to other devices

✅ BLE (Bluetooth Low Energy) #

  • BLE device scanning with service filtering
  • GATT connection management
  • Service and characteristic discovery
  • Read/Write characteristic values
  • Characteristic notifications and subscriptions
  • Connection state monitoring

✅ iBeacon Support #

  • iBeacon advertising (iOS/Android)
  • iBeacon scanning and ranging
  • Proximity detection
  • Region monitoring

📦 Installation #

Add this to your package's pubspec.yaml file:

dependencies:
  universal_bluetooth: ^0.0.1

🔧 Setup #

Android Setup #

Add the following permissions to your android/app/src/main/AndroidManifest.xml:

<!-- Basic Bluetooth permissions -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

<!-- For Android 12+ (API 31+) -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

<!-- Location permissions for BLE and Beacon scanning -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

iOS Setup #

Add the following to your ios/Runner/Info.plist:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app needs access to Bluetooth to communicate with devices</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>This app needs access to Bluetooth to communicate with devices</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs location access for beacon functionality</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs location access for beacon functionality</string>

📱 Usage #

1️⃣ Basic Setup and Status Check #

import 'package:universal_bluetooth/universal_bluetooth.dart';

// Check if Bluetooth is available and enabled
final isAvailable = await UniversalBluetooth.isBluetoothAvailable;
final isEnabled = await UniversalBluetooth.isBluetoothEnabled;

// Request to enable Bluetooth
if (!isEnabled) {
  final enabled = await UniversalBluetooth.requestBluetoothEnable();
}

// Get my Bluetooth address
final address = await UniversalBluetooth.getBluetoothAddress();

2️⃣ Classic Bluetooth Usage #

Device Scanning

// Start scanning for devices
await UniversalBluetooth.startBluetoothScan();

// Listen for discovered devices
UniversalBluetooth.bluetoothScanResults.listen((result) {
  print('Found device: ${result.device.name} (${result.device.address})');
  print('Signal strength: ${result.device.rssi}dBm');
});

// Listen for scan completion
UniversalBluetooth.bluetoothScanFinished.listen((_) {
  print('Scan completed');
});

// Stop scanning
await UniversalBluetooth.stopBluetoothScan();

Make Device Discoverable

// Make device discoverable for 300 seconds
final success = await UniversalBluetooth.startBluetoothDiscoverable(
  duration: 300
);

// Stop discoverable mode
await UniversalBluetooth.stopBluetoothDiscoverable();

Connection and Data Communication

// Connect to a device
await UniversalBluetooth.connectToBluetoothDevice(deviceId);

// Monitor connection state
UniversalBluetooth.bluetoothConnectionStateChanged(deviceId).listen((state) {
  switch (state) {
    case BluetoothConnectionState.connected:
      print('Connected');
      break;
    case BluetoothConnectionState.disconnected:
      print('Disconnected');
      break;
    case BluetoothConnectionState.connecting:
      print('Connecting...');
      break;
    case BluetoothConnectionState.error:
      print('Connection error');
      break;
  }
});

// Send data
final message = "Hello, Bluetooth!";
await UniversalBluetooth.sendBluetoothData(
  deviceId, 
  message.codeUnits
);

// Receive data
UniversalBluetooth.bluetoothDataReceived(deviceId).listen((data) {
  final receivedMessage = String.fromCharCodes(data);
  print('Received message: $receivedMessage');
});

// Disconnect
await UniversalBluetooth.disconnectBluetoothDevice(deviceId);

3️⃣ BLE (Bluetooth Low Energy) Usage #

BLE Scanning

// Start BLE scanning (scan for specific services)
await UniversalBluetooth.startBleScan(
  serviceUuids: ['180F'], // Battery Service UUID (optional)
  timeout: Duration(seconds: 30),
);

// Listen for discovered BLE devices
UniversalBluetooth.bleScanResults.listen((device) {
  print('Found BLE device: ${device.name} (RSSI: ${device.rssi})');
});

// Stop BLE scanning
await UniversalBluetooth.stopBleScan();

BLE Connection and GATT Operations

// Connect to BLE device
await UniversalBluetooth.connectToBleDevice(deviceId);

// Discover services
final services = await UniversalBluetooth.discoverBleServices(deviceId);

// Get characteristics for a service
final characteristics = await UniversalBluetooth.getBleCharacteristics(
  deviceId,
  serviceUuid,
);

// Read characteristic value
final data = await UniversalBluetooth.readBleCharacteristic(
  deviceId,
  serviceUuid,
  characteristicUuid,
);

// Write to characteristic
await UniversalBluetooth.writeBleCharacteristic(
  deviceId,
  serviceUuid,
  characteristicUuid,
  [0x01, 0x02, 0x03],
);

// Subscribe to characteristic notifications
await UniversalBluetooth.subscribeBleCharacteristic(
  deviceId,
  serviceUuid,
  characteristicUuid,
);

// Listen for characteristic value changes
UniversalBluetooth.bleCharacteristicValueChanged(
  deviceId,
  serviceUuid,
  characteristicUuid,
).listen((data) {
  print('Characteristic value changed: $data');
});

// Disconnect BLE device
await UniversalBluetooth.disconnectBleDevice(deviceId);

4️⃣ iBeacon Usage #

iBeacon Advertising

// Request location permission (required for beacon functionality)
final hasPermission = await UniversalBluetooth.requestLocationPermission();

// Start advertising as iBeacon
await UniversalBluetooth.startBeaconAdvertising(
  uuid: 'E2C56DB5-DFFB-48D2-B060-D0F5A71096E0',
  major: 1,
  minor: 100,
  identifier: 'MyBeacon',
);

// Stop beacon advertising
await UniversalBluetooth.stopBeaconAdvertising();

iBeacon Scanning

// Start scanning for beacons
await UniversalBluetooth.startBeaconScanning(
  uuids: ['E2C56DB5-DFFB-48D2-B060-D0F5A71096E0'],
);

// Listen for discovered beacons
UniversalBluetooth.beaconScanResults.listen((beacon) {
  print('Found beacon: ${beacon.uuid}');
  print('Major: ${beacon.major}, Minor: ${beacon.minor}');
  print('Distance: ${beacon.distance}m');
  print('Proximity: ${beacon.proximity}');
});

// Stop beacon scanning
await UniversalBluetooth.stopBeaconScanning();

📊 Data Models #

BluetoothDevice #

class BluetoothDevice {
  final String id;           // Device ID
  final String name;         // Device name
  final String address;      // MAC address
  final bool isConnected;    // Connection status
  final int? rssi;          // Signal strength
  final List<String> serviceUuids; // Service UUID list
}

BleDevice #

class BleDevice {
  final String id;           // Device ID
  final String name;         // Device name
  final String address;      // MAC address
  final int rssi;           // Signal strength
  final List<String> serviceUuids; // Service UUID list
  final bool isConnectable; // Whether device is connectable
}

BeaconDevice #

class BeaconDevice {
  final String uuid;         // Beacon UUID
  final int major;          // Major value
  final int minor;          // Minor value
  final int rssi;           // Signal strength
  final double? distance;   // Estimated distance (meters)
  final BeaconProximity proximity; // Proximity
}

enum BeaconProximity { immediate, near, far, unknown }

BluetoothConnectionState #

enum BluetoothConnectionState {
  disconnected,  // Disconnected
  connecting,    // Connecting
  connected,     // Connected
  disconnecting, // Disconnecting
  error,         // Error
}

🔍 Debug and Extension Functions #

// Get list of connected devices
final connectedDevices = await UniversalBluetoothExtensions.getConnectedDevices();

// Send test data
final result = await UniversalBluetoothExtensions.testDataSend(deviceId);

// Set global method call handler
UniversalBluetoothExtensions.setMethodCallHandler((call) async {
  // Handle custom method calls
});

🎯 Platform Support #

Feature Android iOS
Classic Bluetooth
BLE
iBeacon Advertising
iBeacon Scanning

📋 Requirements #

  • Flutter: 3.3.0+
  • Dart: 3.8.1+
  • Android: API level 21+ (Android 5.0+)
  • iOS: 11.0+

⚠️ Important Notes #

  1. Permissions: Android 12+ requires new Bluetooth permissions
  2. Location Permission: Required for BLE scanning and iBeacon functionality
  3. Background Operation: Additional setup may be required for background operation
  4. iOS Limitations: iOS doesn't provide access to actual Bluetooth MAC addresses for privacy reasons

📝 Complete Example #

import 'package:flutter/material.dart';
import 'package:universal_bluetooth/universal_bluetooth.dart';

class BluetoothExample extends StatefulWidget {
  @override
  _BluetoothExampleState createState() => _BluetoothExampleState();
}

class _BluetoothExampleState extends State<BluetoothExample> {
  List<BluetoothScanResult> devices = [];
  bool isScanning = false;

  @override
  void initState() {
    super.initState();
    _initBluetooth();
  }

  Future<void> _initBluetooth() async {
    // Check and request Bluetooth enable
    final isEnabled = await UniversalBluetooth.isBluetoothEnabled;
    if (!isEnabled) {
      await UniversalBluetooth.requestBluetoothEnable();
    }

    // Listen for scan results
    UniversalBluetooth.bluetoothScanResults.listen((result) {
      setState(() {
        final index = devices.indexWhere(
          (device) => device.device.address == result.device.address,
        );
        if (index >= 0) {
          devices[index] = result;
        } else {
          devices.add(result);
        }
      });
    });
  }

  Future<void> _startScan() async {
    setState(() {
      devices.clear();
      isScanning = true;
    });
    await UniversalBluetooth.startBluetoothScan();
  }

  Future<void> _stopScan() async {
    await UniversalBluetooth.stopBluetoothScan();
    setState(() {
      isScanning = false;
    });
  }

  Future<void> _connectDevice(String deviceId) async {
    try {
      await UniversalBluetooth.connectToBluetoothDevice(deviceId);
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Connecting to device...')),
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Connection failed: $e')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Universal Bluetooth Example'),
        actions: [
          IconButton(
            icon: Icon(isScanning ? Icons.stop : Icons.search),
            onPressed: isScanning ? _stopScan : _startScan,
          ),
        ],
      ),
      body: ListView.builder(
        itemCount: devices.length,
        itemBuilder: (context, index) {
          final result = devices[index];
          final device = result.device;
          return ListTile(
            title: Text(device.name.isNotEmpty ? device.name : 'Unknown Device'),
            subtitle: Text('${device.address}\nRSSI: ${device.rssi}dBm'),
            trailing: ElevatedButton(
              onPressed: () => _connectDevice(device.id),
              child: Text('Connect'),
            ),
            leading: Icon(Icons.bluetooth),
          );
        },
      ),
    );
  }
}

📖 API Reference #

Core Methods #

Method Description
isBluetoothAvailable Check if Bluetooth is available on device
isBluetoothEnabled Check if Bluetooth is currently enabled
requestBluetoothEnable() Request user to enable Bluetooth
getBluetoothAddress() Get device Bluetooth address

Classic Bluetooth #

Method Description
startBluetoothScan() Start scanning for Classic Bluetooth devices
stopBluetoothScan() Stop Classic Bluetooth scanning
startBluetoothDiscoverable({duration}) Make device discoverable
stopBluetoothDiscoverable() Stop discoverable mode
connectToBluetoothDevice(deviceId) Connect to a Classic Bluetooth device
disconnectBluetoothDevice(deviceId) Disconnect from a Classic Bluetooth device
sendBluetoothData(deviceId, data) Send data to connected Classic Bluetooth device

Bluetooth Low Energy #

Method Description
startBleScan({serviceUuids, timeout}) Start BLE scanning with optional filters
stopBleScan() Stop BLE scanning
connectToBleDevice(deviceId) Connect to a BLE device
disconnectBleDevice(deviceId) Disconnect from a BLE device
discoverBleServices(deviceId) Discover services on connected BLE device
getBleCharacteristics(deviceId, serviceUuid) Get characteristics for a service
readBleCharacteristic(deviceId, serviceUuid, characteristicUuid) Read characteristic value
writeBleCharacteristic(deviceId, serviceUuid, characteristicUuid, data) Write to characteristic
subscribeBleCharacteristic(deviceId, serviceUuid, characteristicUuid) Subscribe to characteristic notifications
unsubscribeBleCharacteristic(deviceId, serviceUuid, characteristicUuid) Unsubscribe from characteristic notifications

iBeacon #

Method Description
isBeaconSupported Check if iBeacon is supported
startBeaconAdvertising({uuid, major, minor, identifier}) Start advertising as iBeacon
stopBeaconAdvertising() Stop beacon advertising
startBeaconScanning({uuids}) Start scanning for beacons
stopBeaconScanning() Stop beacon scanning
requestLocationPermission() Request location permission for beacon functionality

🔗 Additional Resources #

For complete examples and advanced usage, check the /example folder which includes:

  • Classic Bluetooth scanning and connection
  • Bidirectional data communication
  • BLE device connection and GATT operations
  • iBeacon advertising and scanning
  • Permission management
  • Error handling

🤝 Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

📄 License #

This project is licensed under the MIT License - see the LICENSE file for details.

🆘 Support #

If you encounter any issues or have questions, please file an issue on the GitHub repository.


Universal Bluetooth Plugin makes it easy to integrate all Bluetooth functionality into your Flutter applications, from simple device connections to complex IoT applications.

1
likes
0
points
14
downloads

Publisher

unverified uploader

Weekly Downloads

A universal Bluetooth plugin for Flutter supporting Classic Bluetooth, BLE, and iBeacon.

Homepage

License

unknown (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on universal_bluetooth

Packages that implement universal_bluetooth