WellNuo/services/ble/index.ts
Sergei 20911fe521 Fix BLE NullPointerException crash on Android
Root cause: react-native-ble-plx v3.5.0 calls Promise.reject(null, ...)
in 17 places in BlePlxModule.java, causing NullPointerException when
BLE operations fail (e.g., device disconnect during WiFi config).

Fixes applied:
- patch-package: Replace all safePromise.reject(null, ...) with
  safePromise.reject(error.errorCode.name(), ...) in native Java code
- Lazy BLE initialization: Defer BleManager creation until first use
- Safe error handling: Add transactionId and safeReject wrapper

Reference: https://github.com/dotintent/react-native-ble-plx/issues/1303

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-26 18:46:35 -08:00

43 lines
1.7 KiB
TypeScript

// BLE Service entry point
import * as Device from 'expo-device';
import { IBLEManager } from './types';
// Determine if BLE is available (real device vs simulator)
export const isBLEAvailable = Device.isDevice;
// Lazy singleton - only create BLEManager when first accessed
let _bleManager: IBLEManager | null = null;
function getBLEManager(): IBLEManager {
if (!_bleManager) {
console.log('[BLE] Creating BLEManager instance (lazy)...');
// Dynamic import to prevent crash on Android startup
if (isBLEAvailable) {
const { RealBLEManager } = require('./BLEManager');
_bleManager = new RealBLEManager();
} else {
const { MockBLEManager } = require('./MockBLEManager');
_bleManager = new MockBLEManager();
}
}
return _bleManager!; // Non-null assertion - we just assigned it above
}
// Proxy object that lazily initializes the real manager
export const bleManager: IBLEManager = {
scanDevices: () => getBLEManager().scanDevices(),
stopScan: () => getBLEManager().stopScan(),
connectDevice: (deviceId: string) => getBLEManager().connectDevice(deviceId),
disconnectDevice: (deviceId: string) => getBLEManager().disconnectDevice(deviceId),
isDeviceConnected: (deviceId: string) => getBLEManager().isDeviceConnected(deviceId),
sendCommand: (deviceId: string, command: string) => getBLEManager().sendCommand(deviceId, command),
getWiFiList: (deviceId: string) => getBLEManager().getWiFiList(deviceId),
setWiFi: (deviceId: string, ssid: string, password: string) => getBLEManager().setWiFi(deviceId, ssid, password),
getCurrentWiFi: (deviceId: string) => getBLEManager().getCurrentWiFi(deviceId),
rebootDevice: (deviceId: string) => getBLEManager().rebootDevice(deviceId),
};
// Re-export types
export * from './types';