Bug(s) or Feature(s)

Bluetooth Device

Connect and communicate with device(s)


The BluetoothDevice is where the magic of communicating with your actual devices takes place. You're always going to be requesting your BluetoothDevice from one of the RNBluetoothClassic functions. Once you've got that device (or a saved address which which you can simulate an address) you're good to go.

import RNBluetoothClassic, {
  BluetoothEventType,
  BluetoothDevice,
} from "react-native-bluetooth-classic";

Common API

The following are available on both Android and IOS.

isConnected

isConnected(): Promise<boolean>

Whether or not the current device is connected - note that like everywhere else connected means that there is an active BluetoothSocket and not just paired.

Requests
  • Look into adding an isPaired() request that does the same

connect

connect(options: Map<string,object>): Promise<boolean>

Connect to the device. This will attempt to open a BluetoothSocket (or some other connection type based on configuration) using the options provided.

async connect() {
  try {
    let connection = await this.props.device.isConnected();
    if (!connection) {
      connection = await this.props.device.connect(this.state.connectionOptions);
    }

    this.setState({connection});
    this.initializeRead();
  } catch (error) {
    // Handle error accordingly
  }
}
Parameters

options: map<string,object> provides a definition of connection properties used at different levels of the library. The following describe the default implementations:

RNBluetoothClassicModule

CONNECTOR_TYPE - specify the connector; defaults to rfcomm

RfcommConnectorThreadImpl

SECURE_SOCKET - whether to initiate connection with secure or insecure socket; defaults to true.

DelimitedStringDeviceConnectionImpl

DELIMITER - delimiter used to split messages; defaults to \n. Providing no delimiter will cause read and onReceivedData to stream all available information with no segmentation.

DEVICE_CHARSET - the character set for encoding String data; defaults to ascii. Android uses Charset values, while IOS uses integer values for determining character sets. See the specific implementation for details.

READ_SIZE - provides the ability to increase the amount of data read per cycle; defaults to 1024. A number of forks have determined that increasing this value improves performance.

READ_TIMEOUT - adds an extra timeout to the read cycle; defaults to 0. This is a hold over from the original implementation with a value of 300, it was removed as the read method is already blocking and had a large number of requests/forks.

let connected = await connect({
  CONNECTOR_TYPE: "rfcomm",
  DELIMITER: "\n",
  DEVICE_CHARSET: Platform.OS === "ios" ? 1536 : "utf-8",
});

disconnect

disconnect(): Promise<boolean>

Attempts to disconnect from the device.

async disconnect() {
  try {
    let disconnected = await this.props.device.disconnect();
    this.setState({connection: !disconnected});
  } catch(error) {
    // Handle error accordingly
  }
}

available

available(): Promise<number>

Requests how much data is available for read. Resolves with a number based on the connection type, for example the DelimitedConnection*Impl(Java) connections return the number of delimited messages not the number of bytes as you might expect.

try {
  let messages = await this.props.device.available();
  if (messages.length > 0) {
    performRead();
  }
} catch (error) {
  // Handle accordingly
}

clear

clear(): Promise<boolean>

Clear all the messages currently in the buffer. This is really only used for manual reads, as listening to received data would automatically clear.

read

read(): Promise<BluetoothMessage>

Reads from the device buffer and returns a BluetoothMessage containing information regarding the data. The amount and type of data is dependant on the native DeviceConnection. The default DelimitedConnection*Impl connections return plain strings, encoded/decoded using the requested Charset

try {
  let message = await this.props.device.read();
  this.setState({ data: message.data });
} catch (error) {
  // Handle error accordingly
}
Errors
  • Any errors occur during reading

write

write(data: string|Buffer, encoding?: string): Promise<boolean>

Attempts to write to the device. Like the read function, this is completely dependant on the DeviceConnection on how this data is written.

Parameters

data: string|buffer must be in the format that your DeviceConnection is expecting. Upon request, the content will be sent to the native side as after being Base64 encoded. This means that if you wish to send byte[] or hex you need to ensure the data is already encoded as such. encoding?: "utf-8" | "ascii" | "utf8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex" | undefined used to specify encoding of non Buffer data prior to sending to native

The default remains to encode strings as utf-8 when not specified.

Errors
  • If the Socket is closed
  • Any other errors occur while writing

onDataReceived

onDataReceived( listener: BluetoothEventListener<BluetoothDeviceReadEvent> ): BluetoothEventSubscription

Provide a listener for incoming data. Without adding a listener data will be appended to the buffer and made available for:

  • read()
  • the next onReceivedData()

This is controlled by an augmented RCTDeviceEmitter and a ported Android version that is based specifically on the BluetoothEventType instead of just a rough estimate.

Parameters

listener: BluetoothEventListener<BluetoothDeviceReadEvent> called when new BluetoothReadEvent is fired.

Returns

BluetoothEventSubscription which must be used to remove() the listener.

initializeRead() {
  this.readSubscription = this.props.device.onDataReceived((data) => this.onReceivedData(data));
}

async onReceivedData(event: BluetoothReadEvent) {
    this.addData({
      ...event,
      timestamp: new Date(),  // Add the current date
      type: 'receive'         // Add a type for UI
    });
  }

Android API

There are no current Android only API.

IOS API

There are no current IOS only API.