BTProvider
A React context provider component that manages Bluetooth Low Energy medical device scanning, connection, and event handling. Provides centralized BLE functionality access throughout the component tree with automatic lifecycle management.
Overview
The BTProvider component serves as the main entry point for BT Management functionality in React Native applications. It initializes the scanning system, manages device connections, and provides event-driven communication for medical device interactions.
Features
- Context Provider: Makes BT functionality available throughout the component tree
- Automatic Scanning: Manages BLE scanning lifecycle with focus-based control
- Event Management: Centralized event handling for device status, measurements, and errors
- Connection Management: Automatic device connection and reconnection handling
- Lifecycle Integration: Proper cleanup and resource management with React lifecycle
- Error Handling: Comprehensive error handling with customizable error callbacks
- Stream Data Support: Real-time data streaming for continuous monitoring devices
- Focus Effect Integration: Automatic start/stop based on screen focus
Props
| Prop | Type | Required | Description |
|---|---|---|---|
bleManager | BleManager | required | BLE manager instance from react-native-ble-plx |
acceptedDevices | T extends readonly IntegratedDevices[] | required | List of accepted devices |
onDeviceFound | (device: BTManagedDevice<T[number]>, manager: BTManager<T>) => void | Callback when a medical device is discovered | |
onError | (data: ErrorCallback) => void | Callback for errors | |
onDeviceStatusChanged | (data: DeviceStatusChangeCallback) => void | Callback for device status changes | |
onResult | (data: ResultCallback<T[number]>) => void | Callback for new measurement data | |
children | ReactNode | required | Child components that will have access to BT context |
Usage Patterns
Basic Setup
import React from "react";
import { BleManager } from "react-native-ble-plx";
import { useFocusEffect } from "@react-navigation/native";
import { BTProvider, DeviceStatus } from "@modules/bt-management";
const bleManager = new BleManager();
const acceptedDevices = [IntegratedDevices.F4];
function App() {
const handleDeviceFound = React.useCallback(
async (device: BTManagedDevice<IntegratedDevices>) => {
console.log("Device discovered:", device.deviceData.name);
// Automatically connect to the device
await device.connect();
},
[],
);
const handleError = React.useCallback((error: ErrorCallback) => {
console.error("Scanning error:", error.message);
// Handle permission issues, Bluetooth state, etc.
}, []);
const handleDeviceStatusChanged = React.useCallback(
(data: DeviceStatusChangeCallback) => {
console.error(`Device error for ${device.name}:`, error);
// Handle device-specific errors
},
[],
);
const handleResult = React.useCallback(
(data: ResultCallback<IntegratedDevices>) => {
console.log("Result:", data);
},
[],
);
return (
<BTProvider
bleManager={bleManager}
onDeviceFound={handleDeviceFound}
onError={handleError}
onDeviceStatusChanged={handleDeviceStatusChanged}
onResult={handleResult}
>
<YourAppComponents />
</BTProvider>
);
}
Performance Considerations
- Efficient Scanning: Automatic scanning lifecycle management prevents battery drain
- Event Optimization: Event subscriptions are properly managed to prevent memory leaks
- Connection Pooling: Single scan instance prevents multiple simultaneous scans
- Automatic Cleanup: All subscriptions and timers are cleaned up on unmount
- Focus Integration: Scanning pauses when screen is not focused
Error Handling
The BTProvider handles various error scenarios:
Scanning Errors
- Bluetooth permission issues
- Bluetooth adapter state problems
- Hardware-related scanning failures
Device Errors
- Connection timeouts
- Device communication failures
- Protocol parsing errors
- Device-specific error conditions
Recovery Mechanisms
- Automatic retry with exponential backoff
- Permission request prompts
- Bluetooth state monitoring
- Device reconnection handling
Testing
Unit Testing
import { render } from "@testing-library/react-native";
import { BTProvider } from "@modules/bt-management";
const mockBleManager = {
enable: jest.fn(),
state: jest.fn().mockResolvedValue("PoweredOn"),
startDeviceScan: jest.fn(),
stopDeviceScan: jest.fn(),
};
describe("BTProvider", () => {
it("initializes scanning on mount", () => {
const onDeviceFound = jest.fn();
const onScanError = jest.fn();
render(
<BTProvider
bleManager={mockBleManager}
onDeviceFound={onDeviceFound}
onScanError={onScanError}
// ... other required props
>
<TestComponent />
</BTProvider>,
);
expect(mockBleManager.startDeviceScan).toHaveBeenCalled();
});
});
Integration Testing
// Test with mock devices
const mockDevice = {
id: "test-device-id",
name: "F4",
connect: jest.fn().mockResolvedValue(true),
discoverAllServicesAndCharacteristics: jest.fn(),
};
// Simulate device discovery
const onDeviceFound = jest.fn();
simulateDeviceDiscovery(mockDevice);
expect(onDeviceFound).toHaveBeenCalledWith(
expect.objectContaining({
deviceData: expect.objectContaining({
name: "F4",
}),
}),
);
Troubleshooting
Common Issues
-
Scanning Not Starting
- Verify Bluetooth permissions are granted
- Check Bluetooth adapter state
- Ensure useFocusEffect is properly imported
-
Devices Not Found
- Verify device is in pairing mode
- Check device is within range
- Ensure device type is supported
-
Connection Failures
- Check device battery level
- Verify BLE services are available
- Monitor for interference
-
Memory Leaks
- Ensure proper cleanup in useFocusEffect
- Verify all subscriptions are removed
- Check for retain cycles in callbacks
Dependencies
react-native-ble-plx: BLE communication@react-navigation/native: useFocusEffect hook@ovok/core: Measurement types