Skip to main content

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

PropTypeRequiredDescription
bleManagerBleManagerrequiredBLE manager instance from react-native-ble-plx
acceptedDevicesT extends readonly IntegratedDevices[]requiredList of accepted devices
onDeviceFound(device: BTManagedDevice<T[number]>, manager: BTManager<T>) => voidCallback when a medical device is discovered
onError(data: ErrorCallback) => voidCallback for errors
onDeviceStatusChanged(data: DeviceStatusChangeCallback) => voidCallback for device status changes
onResult(data: ResultCallback<T[number]>) => voidCallback for new measurement data
childrenReactNoderequiredChild 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

  1. Scanning Not Starting

    • Verify Bluetooth permissions are granted
    • Check Bluetooth adapter state
    • Ensure useFocusEffect is properly imported
  2. Devices Not Found

    • Verify device is in pairing mode
    • Check device is within range
    • Ensure device type is supported
  3. Connection Failures

    • Check device battery level
    • Verify BLE services are available
    • Monitor for interference
  4. 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