react-native-bluetooth-classic

repository·main·Indexed 43 days ago

https://github.com/kenjdavidson/react-native-bluetooth-classic

A React Native bridge for Bluetooth Classic (serial) communication. It implements Bluetooth Adapter on Android and the External Accessory framework on iOS to address the gap left by CoreBluetooth (BLE). Version 1.73.0-rc.17 supports string-based communication via DelimitedStringDeviceConnection and binary data via ByteArrayDeviceConnection, with specific implementations for RFCOMM/SPP connections.

Tokens
14.9K
Snippets
49
Records
74
Agent score
54%

What's inside react-native-bluetooth-classic

  1. Android API Overview

    main

    The Android implementation of react-native-bluetooth-classic is composed of several key classes that manage the lifecycle of Bluetooth connections:

    • RNBluetoothClassicModule: The bridge that manages all communication between the Android native layer and React Native.
    • RNBluetoothClassicPackage: Responsible for providing DeviceConnection configurations to the module. You can provide a custom implementation via MainApplication or react-native.config.js.
    • RNBluetoothClassicPackage.Builder: A fluent API used to create an RNBluetoothClassicPackage with customized ConnectionAcceptors, ConnectionConnectors, and DeviceConnections.
    • ConnectionAcceptor: An interface for accepting connections using the BluetoothAdapter. The default implementation is RfcommAcceptorThreadImpl.
    • ConnectionConnector: An interface for initiating connections to individual devices. The default implementation is RfcommConnectorThreadImpl.
    • DeviceConnection: The core class responsible for all communication between Android and the Bluetooth device. This is the primary extension point for handling different message types, formats, and middleware. Available implementations include:
      • DelimitedStringDeviceConnectionImpl
      • HexDeviceConnectionImpl
  2. Use ConnectionAcceptor to accept Bluetooth connections on Android

    main

    The ConnectionAcceptor is an abstract class used to implement the logic for an Android device to act as a server and accept incoming connections from remote peripherals. It requires a BluetoothAdapter and a set of Properties to function.

    To use it, you typically implement or use a provided implementation (like RfcommConnectionAcceptorThreadImpl), register an AcceptorListener to handle the result, and call run() to start the accepting process on a background thread.

  3. Understand the ConnectionConnector abstraction

    main

    The ConnectionConnector is an abstract class used to implement connection processes for specific remote peripheral types. It serves as the foundation for connecting to a BluetoothDevice using a set of Properties.

    When implementing or using a connector, the lifecycle typically involves:

    1. Instantiating the connector with a BluetoothDevice and Properties.
    2. Adding a ConnectorListener to handle the outcome.
    3. Executing the connection (via the run() method which handles threading).
    4. Receiving either a BluetoothSocket on success or an Exception on failure.
  4. Accessing Android Bluetooth functionality via RNBluetoothClassicModule

    main

    The RNBluetoothClassicModule is the internal Android implementation responsible for managing Bluetooth communication and management. End-users should not interact with RNBluetoothClassicModule directly. Instead, all Bluetooth functionality should be accessed through the high-level React Native API provided by the RNBluetoothModule package.

    Once the library is configured, the module facilitates communication through three primary internal abstractions:

    1. ConnectionAcceptor: Handles incoming Bluetooth connection requests.
    2. ConnectionConnector: Handles initiating outgoing Bluetooth connections.
    3. DeviceConnection: Manages the active communication session with a specific device.
  5. Use the BluetoothDevice class to communicate with devices

    main

    The BluetoothDevice object is the primary interface for communicating with specific Bluetooth devices. You obtain a BluetoothDevice instance by calling functions from RNBluetoothClassic. Once obtained, you can use it to manage connections, read data, and write data.

    import RNBluetoothClassic, {
      BluetoothEventType,
      BluetoothDevice,
    } from "react-native-bluetooth-classic";
  6. Use DelimitedStringDeviceConnection for string-based communication

    main

    The DelimitedStringDeviceConnectionImpl implementation chunks incoming data into messages based on a specific DELIMITER. This is the default connection type if no type is specified during connection.

    Parameters

    • CONNECTION_TYPE: Set to 'delimited' (default).
    • DELIMITER: The character(s) used to split data into messages. Defaults to \n. If you pass an empty delimiter, the full buffer will be sent on read() or onDataReceived.
    • DEVICE_CHARSET: The character set used for encoding/decoding. Defaults to ascii.
    • READ_SIZE: Number of bytes to read during a request. Defaults to 1024.
    • READ_TIMEOUT: Timeout for read operations. Defaults to 0.
    // Default usage (uses \n delimiter and ascii charset)
    let connectedDevice = device.connect({
      CONNECTION_TYPE: 'delimited'
    });
    
    // Explicitly setting a delimiter
    let connectedDevice = device.connect({
      DELIMITER: '\n'
    });
    
    // Explicitly setting a charset
    let connectedDevice = device.connect({
      DEVICE_CHARSET: 'ascii'
    });
  7. Best practices for reading data from a BluetoothDevice

    main

    When reading data from a BluetoothDevice, avoid using onDataReceived() and read() simultaneously. Using both at once can result in half-filled data or random errors.

    Recommended Patterns:

    • Use onDataReceived() to handle read events via a listener.
    • Use read() inside a setInterval loop to continuously poll for data.
    • Choose one method and stick to it for consistent data retrieval.
  8. iOS Environment Requirements and MFi

    main

    On iOS, communicating via Bluetooth Classic requires the External Accessory framework. To use this library on iOS, your hardware must be part of Apple's MFi (Made for iPhone) program.

    Important Note on iOS 17+ Encoding: In iOS 17, a change in how utf encoded strings with newline characters are handled can prevent the default delimiter (newline) from being recognized by the read function. To resolve this, the library has changed its default encoding to nonLossyASCII (Encoding Docs).