The only purpose of this library is to manage the Bluetooth state. Not more, not less.
If you need further functionality like connecting and communicating with a device, please look at react-native-ble-plx.
Requires react-native >=0.75
. See also the requirements of react-native-nitro-modules.
bun add react-native-nitro-modules react-native-bluetooth-state-manager
cd ios && bunx pod-install
# replace bun with npm/yarn/pnpm and bunx with npx
import { BluetoothStateManager } from "react-native-bluetooth-state-manager";
iOS
You must provide a short description of why you need access to Bluetooth in your app. Otherwise, your app will crash when requesting Bluetooth access:
This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSBluetoothAlwaysUsageDescription key with a string value explaining to the user how the app uses this data.
For expo add the following to your app.json
/app.config.js
/app.config.ts
:
{
"ios": {
"infoPlist": {
"NSBluetoothAlwaysUsageDescription": "Your reason to use bluetooth"
}
}
}
Important: The first attempt to check the Bluetooth state will prompt the user for permission to access Bluetooth.
Android
To use requestToEnable()
and requestToDisable()
on Android, you have to add the BLUETOOTH_CONNECT
permission to your AndroidManifest.xml
:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
</manifest>
BLUETOOTH_CONNECT
is a runtime permission, which means you must ask the user at runtime for permission. For that, we recommend react-native-permissions.
import {
useBluetoothState,
BluetoothStateManager,
BluetoothState,
} from "react-native-bluetooth-state-manager";
// Get bluetooth state
// hook
const bluetoothState = useBluetoothState();
// synchronous
const bluetoothState = BluetoothStateManager.getStateSync();
// asynchronous
const bluetoothState = await BluetoothStateManager.getState();
// Event listener
const [bluetoothState, setBluetoothState] = useState<BluetoothState>();
useEffect(() => {
const remove = BluetoothStateManager.addListener((state) => {
setBluetoothState(state);
});
return remove;
}, []);
// Open settings page
await BluetoothStateManager.openSettings();
// Android only
// Ask user to enable bluetooth
await BluetoothStateManager.requestToEnable();
// Ask user to disable bluetooth
await BluetoothStateManager.requestToDisable();
An example is under example/App.tsx
Method | Return Type | OS | Description |
---|---|---|---|
useBluetoothState(enabled: boolean = true) | BluetoothState |
Android, iOS | Hook that returns the current state of the bluetooth service. |
getState() | Promise<BluetoothState> |
Android, iOS | Returns the current state of the bluetooth service. |
getStateSync() | BluetoothState |
Android, iOS | Returns the current state synchronous of the bluetooth service. |
addListener(listener, emitCurrentState) | Subscription |
Android, iOS | Listen for bluetooth state changes. |
openSettings() | Promise<null> |
Android, iOS | Opens the bluetooth settings. Please see below for more details. |
requestToEnable() | Promise<void> |
Android | Show a dialog that allows the user to turn on Bluetooth. |
requestToDisable() | Promise<void> |
Android | Show a dialog that allows the user to turn off Bluetooth. |
Hook that returns the current state of the bluetooth service.
import { useBluetoothState } from "react-native-bluetooth-state-manager";
const enabled = true; // default true
const bluetoothState = useBluetoothState(enabled);
switch (bluetoothState) {
case "Unknown":
case "Resetting":
case "Unsupported":
case "Unauthorized":
case "PoweredOff":
case "PoweredOn":
default:
break;
}
Returns the current state of the bluetooth service.
import { BluetoothStateManager } from "react-native-bluetooth-state-manager";
const bluetoothState = await BluetoothStateManager.getState();
switch (bluetoothState) {
case "Unknown":
case "Resetting":
case "Unsupported":
case "Unauthorized":
case "PoweredOff":
case "PoweredOn":
default:
break;
}
Returns the current state synchronous of the bluetooth service.
import { BluetoothStateManager } from "react-native-bluetooth-state-manager";
const bluetoothState = BluetoothStateManager.getStateSync();
switch (bluetoothState) {
case "Unknown":
case "Resetting":
case "Unsupported":
case "Unauthorized":
case "PoweredOff":
case "PoweredOn":
default:
break;
}
Listen for bluetooth state changes.
import { BluetoothStateManager } from "react-native-bluetooth-state-manager";
BluetoothStateManager.addListener((bluetoothState) => {
// do something...
}, true /*=emitCurrentState*/);
Opens the bluetooth settings.
Tested:
- Android 6.0.1 (Huawei P8 Lite ALE-L21)
- Android 7.1.1 (Galaxy J5 2016)
- Android 8.0 (Galaxy S8+ SM-G955f)
Opens the settings page of the app. Please see here.
BluetoothStateManager.openSettings();
Show a dialog that allows the user to turn on Bluetooth. More here: Android documentation.
- This function is only available on Android.
try {
await BluetoothStateManager.requestToEnable();
} catch (error) {
// Failed
}
Show a dialog that allows the user to turn off Bluetooth.
- This function is only available on Android.
try {
await BluetoothStateManager.requestToDisable();
} catch (error) {
// Failed
}
Why not just use react-native-ble-plx?
Because it's too bloated for my needs.
In several of my projects, I've had to integrate various third-party SDKs that communicate with different Bluetooth devices on the native side. The only functionality I needed on the JavaScript side was checking whether Bluetooth was enabled before starting the third-party SDK.