Bluetooth Connection Plugin

A comprehensive Flutter plugin for connecting to Bluetooth devices, specifically designed for bluetooth machines and similar IoT devices. This plugin provides robust connectivity, data reading capabilities, and real-time data monitoring.

Features

Device Discovery: Scan and list paired Bluetooth devices
Connection Management: Connect to and disconnect from Bluetooth devices
Data Reading: Read data from connected devices with multiple attempt retries
Real-time Listening: Continuous data monitoring with background listening
Multiple UUID Support: Compatible with various Bluetooth protocols (SPP, etc.)
Permission Handling: Automatic Bluetooth permission management for Android 12+
Error Handling: Comprehensive error handling with descriptive error messages

Supported Platforms

  • Android (API 21+)
  • iOS (iOS 11.0+)

Installation

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

dependencies:
  bluetooth_connection_plugin: ^1.0.0

Then run:

flutter pub get

Android Setup

Permissions

The plugin automatically handles all required permissions. The following permissions are included in the plugin's Android manifest:

For Android 12+ (API 31+):

  • BLUETOOTH_SCAN
  • BLUETOOTH_CONNECT
  • BLUETOOTH_ADVERTISE

For Older Android versions:

  • BLUETOOTH
  • BLUETOOTH_ADMIN
  • ACCESS_FINE_LOCATION
  • ACCESS_COARSE_LOCATION

Minimum SDK Version

Ensure your app's android/app/build.gradle has:

android {
    compileSdkVersion 34
    
    defaultConfig {
        minSdkVersion 21  // Required minimum
        targetSdkVersion 34
    }
}

iOS Setup

Permissions

Add the following permissions to your app's ios/Runner/Info.plist:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app needs Bluetooth access to connect to Bluetooth devices and read data from devices.</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>This app needs Bluetooth access to connect to Bluetooth devices and read data from devices.</string>

Minimum iOS Version

Ensure your app's ios/Podfile has:

platform :ios, '11.0'

iOS Bluetooth Behavior

  • Device Discovery: iOS uses Bluetooth Low Energy (BLE) scanning instead of accessing system-paired devices
  • Connection Process: Devices must be discovered first before connecting
  • Background Support: Limited background Bluetooth capabilities due to iOS restrictions
  • Permissions: iOS automatically manages Bluetooth permissions when your app accesses Bluetooth features

Usage

1. Initialize the Plugin

import 'package:bluetooth_connection_plugin/bluetooth_connection_plugin.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    BluetoothConnectionPlugin.initialize();
  }
}

2. Get Paired Devices

Future<void> getPairedDevices() async {
  try {
    List<Map<String, dynamic>> devices = await BluetoothConnectionPlugin.getPairedDevices();
    
    for (var device in devices) {
      print('Device: ${device['name']} - ${device['address']}');
    }
  } on BluetoothException catch (e) {
    print('Error: ${e.message}');
  }
}

3. Connect to a Device

Future<void> connectToDevice(String deviceAddress) async {
  try {
    Map<String, dynamic> result = await BluetoothConnectionPlugin.connectToDevice(deviceAddress);
    print('Connected to: ${result['deviceName']}');
  } on BluetoothException catch (e) {
    print('Connection failed: ${e.message}');
  }
}

4. Read Data

Future<void> getData() async {
  try {
    BluetoothData data = await BluetoothConnectionPlugin.readData();
    
    if (data.data.isNotEmpty) {
    // Automatically extracted weight value
     
      print('Raw data: ${data.rawData}');
      print('Timestamp: ${data.dateTime}');
    }
  } on BluetoothException catch (e) {
    print('Read failed: ${e.message}');
  }
}

5. Real-time Data Listening

Future<void> startListening() async {
  try {
    await BluetoothConnectionPlugin.startListening();
    print('Started listening for data');
    
    // Data will be received via method channel callbacks
    // Implement _handleMethodCall to receive data
  } on BluetoothException catch (e) {
    print('Start listening failed: ${e.message}');
  }
}

Future<void> stopListening() async {
  try {
    await BluetoothConnectionPlugin.stopListening();
    print('Stopped listening');
  } on BluetoothException catch (e) {
    print('Stop listening failed: ${e.message}');
  }
}

6. Disconnect Device

Future<void> disconnect() async {
  try {
    await BluetoothConnectionPlugin.disconnectDevice();
    print('Disconnected from device');
  } on BluetoothException catch (e) {
    print('Disconnect failed: ${e.message}');
  }
}

7. Check Connection Status

Future<void> checkConnection() async {
  try {
    bool isConnected = await BluetoothConnectionPlugin.isConnected();
    print('Connection status: $isConnected');
  } on BluetoothException catch (e) {
    print('Status check failed: ${e.message}');
  }
}

Data Models

BluetoothData

Represents data received from a Bluetooth device:

class BluetoothData {
  final String data;          // Processed data
  final String rawData;       // Raw data from device
  final int bytesRead;        // Number of bytes read
  final int timestamp;        // Timestamp in milliseconds
  
}

BluetoothDeviceInfo

Represents a Bluetooth device:

class BluetoothDeviceInfo {
  final String name;          // Device name
  final String address;       // Device MAC address
  final String type;          // Device type (Classic, LE, Dual Mode)
}

BluetoothException

Custom exception for Bluetooth operations:

class BluetoothException implements Exception {
  final String code;          // Error code
  final String message;       // Error message
}

The extraction algorithm:

  • Removes non-numeric characters except decimals, minus, and plus signs
  • Handles multiple values by selecting the first valid number
  • Works with various data formats from different weighing machine brands

Complete Example

Troubleshooting

Common Issues

  1. Permission Denied: Ensure Bluetooth permissions are granted in Android settings
  2. Connection Failed: Check if the device is paired and within range
  3. No Data: Some devices require specific commands to start data transmission
  4. Compatibility: Test with your specific machine model

Debug Tips

  1. Enable detailed logging in your app
  2. Check raw data format from your device
  3. Test connection with Bluetooth terminal apps first
  4. Verify device pairing in Android Bluetooth settings

Supported Device Types

  • Digital weighing scales
  • Medical weighing machines
  • Industrial scales
  • Bluetooth serial devices
  • Any device using SPP (Serial Port Profile)

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

For issues and feature requests, please use the GitHub Issues page.

Changelog

See CHANGELOG.md for a detailed list of changes.