React Native BLE Plx

3.5.1 · active · verified Sun Apr 19

react-native-ble-plx is a comprehensive React Native library providing a low-level API for interacting with Bluetooth Low Energy (BLE) devices on both iOS and Android platforms. The current stable version is 3.5.1, with recent releases indicating an active development and maintenance cadence addressing bugs and improvements. It supports core BLE functionalities such as observing the Bluetooth adapter state, scanning for devices, connecting to peripherals, discovering services and characteristics, reading/writing characteristic values, observing notifications/indications, reading RSSI, and negotiating MTU. A key differentiator is its inclusion of an Expo config plugin for easier integration into managed Expo workflows (requiring prebuilding). The library explicitly does not support Bluetooth Classic, inter-phone BLE communication (peripheral mode), device bonding, or beacon technologies. It is built to provide robust control over BLE interactions in React Native applications.

Common errors

Warnings

Install

Imports

Quickstart

Initializes the BleManager, requests necessary Bluetooth permissions for Android, monitors Bluetooth adapter state, and performs a device scan, logging found devices. It also demonstrates how to handle state changes and stop scanning.

import { BleManager, State } from 'react-native-ble-plx';
import { PermissionsAndroid, Platform } from 'react-native';

const manager = new BleManager();

async function requestBluetoothPermissions() {
  if (Platform.OS === 'ios') {
    return true; // iOS handles permissions differently, usually in Info.plist
  }

  if (Platform.OS === 'android') {
    const apiLevel = Platform.Version;
    if (apiLevel < 31) { // Android 11 (API 30) and below
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
        {
          title: 'Location Permission',
          message: 'Bluetooth Low Energy requires Location Permission',
          buttonNeutral: 'Ask Me Later',
          buttonNegative: 'Cancel',
          buttonPositive: 'OK',
        }
      );
      return granted === PermissionsAndroid.RESULTS.GRANTED;
    } else { // Android 12 (API 31) and above
      const granted = await PermissionsAndroid.requestMultiple([
        PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN,
        PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
      ]);
      return (
        granted['android.permission.BLUETOOTH_SCAN'] === PermissionsAndroid.RESULTS.GRANTED &&
        granted['android.permission.BLUETOOTH_CONNECT'] === PermissionsAndroid.RESULTS.GRANTED &&
        granted['android.permission.ACCESS_FINE_LOCATION'] === PermissionsAndroid.RESULTS.GRANTED
      );
    }
  }
  return false;
}

export const scanForDevices = async () => {
  const hasPermission = await requestBluetoothPermissions();
  if (!hasPermission) {
    console.log('Bluetooth permissions not granted.');
    return;
  }

  const subscription = manager.onStateChange((state) => {
    if (state === State.PoweredOn) {
      console.log('Bluetooth is powered on, starting scan...');
      manager.startDeviceScan(null, { allowDuplicates: false }, (error, device) => {
        if (error) {
          console.error('Scan error:', error);
          return;
        }
        if (device) {
          console.log('Found device:', device.name || device.id);
          // Example: Stop scan after finding one device
          manager.stopDeviceScan();
          // subscription.remove(); // Unsubscribe from state changes
        }
      });
      subscription.remove(); // Remove state change listener after successful scan initiation
    } else {
      console.log('Bluetooth state:', state);
    }
  }, true);
};

// To stop scanning, typically called after a timeout or finding a device
// manager.stopDeviceScan();

// Don't forget to destroy the manager when your component unmounts or app closes
// manager.destroy();

view raw JSON →