onAccessPermissionChanged
Optional callback prop on <BTProvider>. Fires whenever the OS-level Bluetooth + Location permission grant state changes — on initial mount with the current state, and again whenever the user toggles it in Settings while the app is alive.
This is paired with the permissionFallback prop, which renders fallback UI when access is not granted.
Signature
onAccessPermissionChanged?: (accessPermission: boolean) => void;
accessPermission === true when all required permissions are granted (BLUETOOTH_SCAN, BLUETOOTH_CONNECT, ACCESS_FINE_LOCATION on Android; NSBluetoothAlwaysUsageDescription accepted on iOS). false when any one of them is missing or has been revoked.
When it fires
| Trigger | Value |
|---|---|
| Initial mount, all grants present | true |
| Initial mount, any grant missing | false |
| User backgrounds app → opens Settings → grants permission → returns | true |
| User backgrounds app → opens Settings → revokes permission → returns | false |
| OS revokes Bluetooth at runtime (rare) | false |
The callback fires synchronously on app foreground via a listener registered by the provider. You do not need to poll or check permission status yourself.
Usage with permissionFallback
import React, { useCallback, useState } from "react";
import { Button, Linking, Text, View } from "react-native";
import { BleManager } from "react-native-ble-plx";
import { BTProvider, IntegratedDevices } from "@ovok/native";
const bleManager = new BleManager();
const acceptedDevices = [IntegratedDevices.BP2] as const;
function PermissionDeniedCard() {
return (
<View style={{ padding: 24, gap: 12 }}>
<Text style={{ fontSize: 18, fontWeight: "600" }}>
Bluetooth Permission Required
</Text>
<Text>
We need Bluetooth permission to pair with your medical device. Tap below
to open Settings and grant access.
</Text>
<Button title="Open Settings" onPress={() => Linking.openSettings()} />
</View>
);
}
function MyApp() {
const [hasPermission, setHasPermission] = useState<boolean | null>(null);
const handleAccessPermissionChanged = useCallback((granted: boolean) => {
setHasPermission(granted);
if (!granted) {
console.warn("Bluetooth permission denied — children will not mount");
}
}, []);
return (
<BTProvider
bleManager={bleManager}
acceptedDevices={acceptedDevices}
onAccessPermissionChanged={handleAccessPermissionChanged}
permissionFallback={() => <PermissionDeniedCard />}
>
<YourScreens />
</BTProvider>
);
}
What permissionFallback actually renders
When the grant state is false, BTProvider mounts permissionFallback() IN PLACE OF children. This means any BT-dependent UI inside children is guaranteed not to render without permissions — you don't need a permission check inside every child.
Only permissionFallback is rendered while access is missing. The moment the user grants access (via Settings → return to app), the provider re-mounts children and resumes scanning.
If permissionFallback is omitted, BTProvider renders nothing while access is missing — children are unmounted, no fallback UI appears. Always supply a fallback unless you've handled the empty state at a higher level.
Difference from onError permission failures
onError also fires for permission-related BLE errors (e.g. a scan started before grant + permission denied mid-scan). The distinction:
onAccessPermissionChanged(false)→ the OS-level grant flipped. This is the right place to swap UI.onError({ error })with a permission message → an in-flight BLE operation hit a permission wall. Often a transient artifact; the nextonAccessPermissionChangedwill follow with the actual grant state.
Treat onAccessPermissionChanged as authoritative. Use onError for telemetry, not for state.
Don't trigger requests manually
The SDK doesn't expose a requestPermission() method, and you shouldn't call PermissionsAndroid.request(...) directly either — the BleManager itself issues the request on first scan. Your job in permissionFallback is to drive the user toward Settings (via Linking.openSettings()) once an initial denial has already happened.
Related
- BTProvider — full provider reference (including
permissionFallback) - on-error — transient permission errors during BLE ops