import BleManager, { BleConnectPeripheralEvent, BleDisconnectPeripheralEvent, BleManagerDidUpdateValueForCharacteristicEvent, BleScanCallbackType, BleScanMatchMode, BleScanMode, Peripheral as PeripheralWithoutConnectInfo, } from 'react-native-ble-manager'; import { EmitterSubscription, NativeEventEmitter, NativeModules, PermissionsAndroid, Platform, } from 'react-native'; import Buffer from 'buffer'; export type Peripheral = PeripheralWithoutConnectInfo & { connected?: boolean; connecting?: boolean; }; type Events = { bleManagerStartSuccess: () => void | undefined; bleManagerStartError: () => void | undefined; bleManagerStopScan: () => void | undefined; bleManagerStartScan: () => void | undefined; bleManagerDiscoverPeripheral: (peripheral: Peripheral) => void | undefined; bleManagerDisconnectPeripheral: ( event: BleDisconnectPeripheralEvent, ) => void | undefined; bleManagerDidUpdateValueForCharacteristic: ( event: BleManagerDidUpdateValueForCharacteristicEvent, ) => void | undefined; bleManagerConnectPeripheral: ( event: BleConnectPeripheralEvent, ) => void | undefined; }; export default class BleService { private _bleManagerModule = NativeModules.BleManager; private _bleManagerEmitter = new NativeEventEmitter(this._bleManagerModule); private _events: Events; private _listeners: EmitterSubscription[]; private _peripherals: Map; constructor() { this._listeners = []; this._events = {}; this._peripherals = new Map(); BleManager.start({showAlert: false}) .then(() => { this.runEvent(this._events.bleManagerStartSuccess); console.debug('[BleService]: BleManager started.'); }) .catch((err: any) => { this.runEvent(this._events.bleManagerStartError); console.debug('[BleService]: BeManager could not be started.', err); }); this.handle_permissions(); } setEvents(events: Events) { this._events = events; this.setupListiners(events); } handle_permissions() { // po requestach, jak sie zrobi .then() nastepnie gdy (resoult) cos zwroci to oznacza, że ma perma jak nie to nie ma. if (Platform.OS === 'android') { if (Platform.Version >= 31) PermissionsAndroid.requestMultiple([ PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN, PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT, ]); else if (Platform.Version >= 23) PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, ); } } scan() { this.runEvent(this._events.bleManagerStartScan); this.clearPeripherals(); BleManager.scan([], 3, false, { matchMode: BleScanMatchMode.Sticky, scanMode: BleScanMode.LowLatency, callbackType: BleScanCallbackType.AllMatches, }) .then(() => { console.debug('[startScan] scan promise returned successfully.'); }) .catch((err: any) => { console.error('[startScan] ble scan returned in error', err); }); } destroy() { this.destroyListiners(); } getPeripherals() { return this._peripherals; } connect(p: Peripheral) { return BleManager.connect(p.id); } async read(peripheral: Peripheral) { await BleManager.requestMTU(peripheral.id, 512); BleManager.startNotification( peripheral.id, '6e400001-b5a3-f393-e0a9-e50e24dcca9e', '6e400003-b5a3-f393-e0a9-e50e24dcca9e', ) .then(a => { // Success code console.log('--------'); console.log(a); console.log('--------'); }) .catch(error => { // Failure code console.log(error); }); } private addPeripheral(p: Peripheral) { this._peripherals.set(p.id, p); } private clearPeripherals() { this._peripherals = new Map(); } private destroyListiners() { for (const listener of this._listeners) { if (listener) listener.remove(); } } private setupListiners(events: Events) { this.destroyListiners(); this._listeners = [ this._bleManagerEmitter.addListener( 'BleManagerDiscoverPeripheral', peripheral => { this.addPeripheral(peripheral); this.runEvent(events.bleManagerDiscoverPeripheral, peripheral); }, ), this._bleManagerEmitter.addListener('BleManagerStopScan', () => this.runEvent(events.bleManagerStopScan), ), this._bleManagerEmitter.addListener( 'BleManagerDisconnectPeripheral', event => this.runEvent(events.bleManagerDisconnectPeripheral, event), ), this._bleManagerEmitter.addListener( 'BleManagerDidUpdateValueForCharacteristic', event => this.runEvent( events.bleManagerDidUpdateValueForCharacteristic, event, ), ), this._bleManagerEmitter.addListener( 'BleManagerConnectPeripheral', event => this.runEvent(events.bleManagerConnectPeripheral, event), ), ]; } private runEvent( event: CallableFunction | undefined, ...optionalParams: any[] ): void { if (event) { event(...optionalParams); } } }