@mpxjs/api-proxy 2.10.15 → 2.10.16-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,852 @@
1
+ import { noop, type } from '@mpxjs/utils'
2
+ import mpx from '@mpxjs/core'
3
+ import { Platform, PermissionsAndroid } from 'react-native'
4
+ import { base64ToArrayBuffer } from '../base/index'
5
+
6
+ // BleManager 相关
7
+ // 全局状态管理
8
+ let bleManagerInitialized = false
9
+ let DiscoverPeripheralSubscription = null
10
+ let updateStateSubscription = null
11
+ let discovering = false
12
+ let getDevices = [] // 记录已扫描的设备列表
13
+ const deviceFoundCallbacks = []
14
+ const onStateChangeCallbacks = []
15
+ const characteristicCallbacks = []
16
+ const onBLEConnectionStateCallbacks = []
17
+ let characteristicSubscriptions = {}
18
+ const connectedDevices = new Set()
19
+ let createBLEConnectionTimeout = null
20
+ const BLEDeviceCharacteristics = {} // 记录已连接设备的特征值
21
+ const connectedDeviceId = []
22
+
23
+ // 请求蓝牙权限
24
+ const requestBluetoothPermission = async () => {
25
+ if (__mpx_mode__ === 'android') {
26
+ const permissions = []
27
+ if (Platform.Version >= 23 && Platform.Version < 31) {
28
+ permissions.push(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION)
29
+ } else if (Platform.Version >= 31) {
30
+ permissions.push(
31
+ PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN,
32
+ PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT
33
+ )
34
+ }
35
+
36
+ if (permissions.length === 0) {
37
+ return true
38
+ }
39
+ const granted = await PermissionsAndroid.requestMultiple(permissions)
40
+ return Object.values(granted).every(
41
+ result => result === PermissionsAndroid.RESULTS.GRANTED
42
+ )
43
+ }
44
+ return true
45
+ }
46
+
47
+ const removeBluetoothDevicesDiscovery = function () {
48
+ if (DiscoverPeripheralSubscription) {
49
+ DiscoverPeripheralSubscription.remove()
50
+ DiscoverPeripheralSubscription = null
51
+ }
52
+ }
53
+ const removeUpdateStateSubscription = function () {
54
+ if (updateStateSubscription && onStateChangeCallbacks.length === 0 && onBLEConnectionStateCallbacks.length === 0) {
55
+ updateStateSubscription.remove()
56
+ updateStateSubscription = null
57
+ }
58
+ }
59
+ const commonFailHandler = function (errMsg, fail, complete) {
60
+ const result = {
61
+ errMsg
62
+ }
63
+ if (!bleManagerInitialized) {
64
+ Object.assign(result, {
65
+ errCode: 10000,
66
+ errno: 1500101
67
+ })
68
+ }
69
+ fail(result)
70
+ complete(result)
71
+ }
72
+
73
+ function openBluetoothAdapter (options = {}) {
74
+ const BleManager = require('react-native-ble-manager').default
75
+ const { success = noop, fail = noop, complete = noop } = options
76
+ let bluetoothPermission = requestBluetoothPermission
77
+ if (mpx.config?.rnConfig?.bluetoothPermission) { // 安卓需要验证权限,开放给用户可以自定义验证权限的方法
78
+ bluetoothPermission = mpx.config.rnConfig.bluetoothPermission
79
+ }
80
+ // 先请求权限,再初始化蓝牙管理器
81
+ bluetoothPermission().then((hasPermissions) => {
82
+ if (!hasPermissions) {
83
+ commonFailHandler('openBluetoothAdapter:fail no permission', fail, complete)
84
+ return
85
+ }
86
+
87
+ if (bleManagerInitialized) {
88
+ commonFailHandler('openBluetoothAdapter:fail already opened', fail, complete)
89
+ return
90
+ }
91
+
92
+ BleManager.start({ showAlert: false }).then(() => {
93
+ bleManagerInitialized = true
94
+
95
+ // 检查蓝牙状态
96
+ setTimeout(() => {
97
+ BleManager.checkState().then((state) => {
98
+ if (state === 'on') {
99
+ const result = {
100
+ errno: 0,
101
+ errMsg: 'openBluetoothAdapter:ok'
102
+ }
103
+ success(result)
104
+ complete(result)
105
+ } else {
106
+ commonFailHandler('openBluetoothAdapter:fail bluetooth not enabled', fail, complete)
107
+ }
108
+ }).catch((error) => {
109
+ commonFailHandler('openBluetoothAdapter:fail ' + (typeof error === 'string' ? error : ''), fail, complete)
110
+ })
111
+ }, 1000)
112
+ }).catch((error) => {
113
+ commonFailHandler('openBluetoothAdapter:fail ' + (typeof error === 'string' ? error : ''), fail, complete)
114
+ })
115
+ }).catch(() => {
116
+ commonFailHandler('openBluetoothAdapter:fail no permission', fail, complete)
117
+ })
118
+ }
119
+
120
+ function closeBluetoothAdapter (options = {}) {
121
+ const BleManager = require('react-native-ble-manager').default
122
+ const { success = noop, fail = noop, complete = noop } = options
123
+ if (!bleManagerInitialized) {
124
+ const result = {
125
+ errMsg: 'closeBluetoothAdapter:fail 请先调用 wx.openBluetoothAdapter 接口进行初始化操作'
126
+ }
127
+ fail(result)
128
+ complete(result)
129
+ return
130
+ }
131
+ try {
132
+ // 停止扫描
133
+ if (discovering) {
134
+ BleManager.stopScan()
135
+ discovering = false
136
+ }
137
+
138
+ if (createBLEConnectionTimeout) { // 清除掉正在连接的蓝牙设备
139
+ clearTimeout(createBLEConnectionTimeout)
140
+ createBLEConnectionTimeout = null
141
+ }
142
+
143
+ removeUpdateStateSubscription()
144
+ // 清理状态
145
+ bleManagerInitialized = false
146
+ discovering = false
147
+ getDevices = []
148
+ connectedDeviceId.length = 0
149
+ connectedDevices.forEach((id) => {
150
+ BleManager.disconnect(id).catch(() => {})
151
+ })
152
+ connectedDevices.clear()
153
+ deviceFoundCallbacks.length = 0
154
+ onStateChangeCallbacks.length = 0
155
+ characteristicCallbacks.length = 0
156
+ onBLEConnectionStateCallbacks.length = 0
157
+ if (valueForCharacteristicSubscriptions) {
158
+ valueForCharacteristicSubscriptions.remove()
159
+ valueForCharacteristicSubscriptions = null
160
+ }
161
+
162
+ removeBluetoothDevicesDiscovery()
163
+
164
+ // 清理订阅
165
+ Object.keys(characteristicSubscriptions).forEach(key => {
166
+ if (characteristicSubscriptions[key]) {
167
+ characteristicSubscriptions[key].remove()
168
+ }
169
+ })
170
+ characteristicSubscriptions = {}
171
+
172
+ const result = {
173
+ errMsg: 'closeBluetoothAdapter:ok'
174
+ }
175
+ success(result)
176
+ complete(result)
177
+ } catch (error) {
178
+ const result = {
179
+ errMsg: 'closeBluetoothAdapter:fail ' + error.message
180
+ }
181
+ fail(result)
182
+ complete(result)
183
+ }
184
+ }
185
+
186
+ function startBluetoothDevicesDiscovery (options = {}) {
187
+ const BleManager = require('react-native-ble-manager').default
188
+ const {
189
+ services = [],
190
+ allowDuplicatesKey = false,
191
+ success = noop,
192
+ fail = noop,
193
+ complete = noop
194
+ } = options
195
+
196
+ if (!bleManagerInitialized) {
197
+ commonFailHandler('startBluetoothDevicesDiscovery:fail ble adapter hans\'t been opened or ble is unavailable.', fail, complete)
198
+ return
199
+ }
200
+ DiscoverPeripheralSubscription = BleManager.onDiscoverPeripheral((device) => {
201
+ const advertising = device.advertising || {}
202
+ const advertisData = advertising.manufacturerData?.data || null
203
+ const deviceInfo = {
204
+ deviceId: device.id,
205
+ name: device.name || advertising.localName || '未知设备',
206
+ RSSI: device.rssi || 0,
207
+ advertisData: advertisData ? base64ToArrayBuffer(advertisData) : advertisData, // todo需要转换
208
+ advertisServiceUUIDs: advertising.serviceUUIDs || [],
209
+ localName: advertising.localName || '',
210
+ serviceData: advertising.serviceData || {},
211
+ connectable: advertising.isConnectable || false
212
+ }
213
+ if (allowDuplicatesKey === false) {
214
+ const existingDeviceIndex = getDevices.findIndex(existingDevice => existingDevice.deviceId === deviceInfo.deviceId)
215
+ if (existingDeviceIndex > -1) {
216
+ return
217
+ }
218
+ }
219
+ deviceFoundCallbacks.forEach(cb => {
220
+ if (type(cb) === 'Function') {
221
+ cb({
222
+ devices: [deviceInfo]
223
+ })
224
+ }
225
+ })
226
+ getDevices.push(deviceInfo)
227
+ // 处理设备发现逻辑
228
+ })
229
+ BleManager.scan(services, 0, allowDuplicatesKey).then((res) => { // 必须,没有开启扫描,onDiscoverPeripheral回调不会触发
230
+ onStateChangeCallbacks.forEach(cb => {
231
+ if (type(cb) === 'Function') {
232
+ cb({
233
+ available: true,
234
+ discovering: true
235
+ })
236
+ }
237
+ })
238
+ discovering = true
239
+ getDevices = [] // 清空之前的发现设备列表
240
+ const result = {
241
+ errMsg: 'startBluetoothDevicesDiscovery:ok',
242
+ isDiscovering: true
243
+ }
244
+ success(result)
245
+ complete(result)
246
+ }).catch((error) => {
247
+ commonFailHandler('startBluetoothDevicesDiscovery:fail ' + (typeof error === 'string' ? error : ''), fail, complete)
248
+ })
249
+ }
250
+
251
+ function stopBluetoothDevicesDiscovery (options = {}) {
252
+ const BleManager = require('react-native-ble-manager').default
253
+ const { success = noop, fail = noop, complete = noop } = options
254
+
255
+ if (!bleManagerInitialized) {
256
+ commonFailHandler('stopBluetoothDevicesDiscovery:fail ble adapter hans\'t been opened or ble is unavailable.', fail, complete)
257
+ return
258
+ }
259
+ removeBluetoothDevicesDiscovery()
260
+ BleManager.stopScan().then(() => {
261
+ discovering = false
262
+ onStateChangeCallbacks.forEach(cb => {
263
+ if (type(cb) === 'Function') {
264
+ cb({
265
+ available: true,
266
+ discovering: false
267
+ })
268
+ }
269
+ })
270
+ const result = {
271
+ errMsg: 'stopBluetoothDevicesDiscovery:ok'
272
+ }
273
+ success(result)
274
+ complete(result)
275
+ }).catch((error) => {
276
+ commonFailHandler('stopBluetoothDevicesDiscovery:fail ' + (typeof error === 'string' ? error : ''), fail, complete)
277
+ })
278
+ }
279
+
280
+ function onBluetoothDeviceFound (callback) {
281
+ if (deviceFoundCallbacks.indexOf(callback) === -1) {
282
+ deviceFoundCallbacks.push(callback)
283
+ }
284
+ }
285
+
286
+ function offBluetoothDeviceFound (callback) {
287
+ const index = deviceFoundCallbacks.indexOf(callback)
288
+ if (index > -1) {
289
+ deviceFoundCallbacks.splice(index, 1)
290
+ }
291
+ }
292
+
293
+ function getConnectedBluetoothDevices (options = {}) {
294
+ const BleManager = require('react-native-ble-manager').default
295
+ const { services = [], success = noop, fail = noop, complete = noop } = options
296
+
297
+ if (!bleManagerInitialized) {
298
+ commonFailHandler('getConnectedBluetoothDevices:fail 请先调用 wx.openBluetoothAdapter 接口进行初始化操作', fail, complete)
299
+ return
300
+ }
301
+
302
+ BleManager.getConnectedPeripherals(services).then((peripherals) => {
303
+ const devices = peripherals.map(peripheral => ({
304
+ deviceId: peripheral.id,
305
+ name: peripheral.name || '未知设备'
306
+ }))
307
+ const result = {
308
+ errMsg: 'getConnectedBluetoothDevices:ok',
309
+ devices: devices
310
+ }
311
+ success(result)
312
+ complete(result)
313
+ }).catch((error) => {
314
+ commonFailHandler('getConnectedBluetoothDevices:fail ' + (typeof error === 'string' ? error : ''), fail, complete)
315
+ })
316
+ }
317
+
318
+ function getBluetoothAdapterState (options = {}) {
319
+ const BleManager = require('react-native-ble-manager').default
320
+ const { success = noop, fail = noop, complete = noop } = options
321
+
322
+ if (!bleManagerInitialized) {
323
+ commonFailHandler('getBluetoothAdapterState:fail ble adapter need open first.', fail, complete)
324
+ return
325
+ }
326
+
327
+ BleManager.checkState().then((state) => {
328
+ const result = {
329
+ errMsg: 'getBluetoothAdapterState:ok',
330
+ discovering,
331
+ available: state === 'on'
332
+ }
333
+ success(result)
334
+ complete(result)
335
+ }).catch((error) => {
336
+ commonFailHandler('getBluetoothAdapterState:fail ' + (typeof error === 'string' ? error : ''), fail, complete)
337
+ })
338
+ }
339
+ function onDidUpdateState () {
340
+ const BleManager = require('react-native-ble-manager').default
341
+ updateStateSubscription = BleManager.onDidUpdateState((state) => {
342
+ onStateChangeCallbacks.forEach(cb => {
343
+ if (type(cb) === 'Function') {
344
+ cb({
345
+ available: state.state === 'on',
346
+ discovering: state.state === 'on' ? discovering : false
347
+ })
348
+ }
349
+ })
350
+ if (onBLEConnectionStateCallbacks.length && connectedDeviceId.length && state.state !== 'on') {
351
+ connectedDeviceId.forEach((id) => {
352
+ onBLEConnectionStateCallbacks.forEach(cb => {
353
+ if (type(cb) === 'Function') {
354
+ cb({
355
+ deviceId: id,
356
+ connected: false
357
+ })
358
+ }
359
+ })
360
+ })
361
+ }
362
+ })
363
+ }
364
+
365
+ function onBluetoothAdapterStateChange (callback) {
366
+ if (!updateStateSubscription) {
367
+ onDidUpdateState()
368
+ }
369
+ if (onStateChangeCallbacks.indexOf(callback) === -1) {
370
+ onStateChangeCallbacks.push(callback)
371
+ }
372
+ }
373
+
374
+ function offBluetoothAdapterStateChange (callback) {
375
+ const index = onStateChangeCallbacks.indexOf(callback)
376
+ if (index > -1) {
377
+ onStateChangeCallbacks.splice(index, 1)
378
+ }
379
+ if (deviceFoundCallbacks.length === 0) {
380
+ removeUpdateStateSubscription()
381
+ }
382
+ }
383
+
384
+ function getBluetoothDevices (options = {}) { // 该能力只是获取应用级别已连接设备列表,非手机级别的已连接设备列表
385
+ const { success = noop, fail = noop, complete = noop } = options
386
+ if (!bleManagerInitialized) {
387
+ const result = {
388
+ errMsg: 'getBluetoothDevices:fail ble adapter hans\'t been opened or ble is unavailable.'
389
+ }
390
+ fail(result)
391
+ complete(result)
392
+ return
393
+ }
394
+ const result = {
395
+ errMsg: 'getBluetoothDevices:ok',
396
+ devices: getDevices // 返回已扫描的设备列表
397
+ }
398
+ success(result)
399
+ complete(result)
400
+ }
401
+
402
+ function writeBLECharacteristicValue (options = {}) {
403
+ const BleManager = require('react-native-ble-manager').default
404
+ const { deviceId, serviceId, characteristicId, value, success = noop, fail = noop, complete = noop } = options
405
+ if (!deviceId || !serviceId || !characteristicId || !value) {
406
+ const result = {
407
+ errMsg: 'writeBLECharacteristicValue:ok',
408
+ errno: 1509000
409
+ }
410
+ success(result)
411
+ complete(result)
412
+ return
413
+ }
414
+
415
+ // 将ArrayBuffer转换为byte array
416
+ const bytes = Array.from(new Uint8Array(value))
417
+ BleManager.write(deviceId, serviceId, characteristicId, bytes).then(() => {
418
+ const result = {
419
+ errMsg: 'writeBLECharacteristicValue:ok'
420
+ }
421
+ success(result)
422
+ complete(result)
423
+ }).catch((error) => {
424
+ const result = {
425
+ errMsg: 'writeBLECharacteristicValue:fail ' + (typeof error === 'string' ? error : '')
426
+ }
427
+ fail(result)
428
+ complete(result)
429
+ })
430
+ }
431
+
432
+ function readBLECharacteristicValue (options = {}) {
433
+ const BleManager = require('react-native-ble-manager').default
434
+ const { deviceId, serviceId, characteristicId, success = noop, fail = noop, complete = noop } = options
435
+
436
+ if (!deviceId || !serviceId || !characteristicId) {
437
+ const result = {
438
+ errMsg: 'readBLECharacteristicValue:ok',
439
+ errno: 1509000
440
+ }
441
+ success(result)
442
+ complete(result)
443
+ return
444
+ }
445
+
446
+ BleManager.read(deviceId, serviceId, characteristicId).then((data) => {
447
+ // 将byte array转换为ArrayBuffer
448
+ const buffer = new ArrayBuffer(data.length)
449
+ const view = new Uint8Array(buffer)
450
+ data.forEach((byte, index) => {
451
+ view[index] = byte
452
+ })
453
+
454
+ const result = {
455
+ errMsg: 'readBLECharacteristicValue:ok',
456
+ value: buffer
457
+ }
458
+ success(result)
459
+ complete(result)
460
+ }).catch((error) => {
461
+ const result = {
462
+ errMsg: 'readBLECharacteristicValue:fail ' + (typeof error === 'string' ? error : '')
463
+ }
464
+ fail(result)
465
+ complete(result)
466
+ })
467
+ }
468
+
469
+ function notifyBLECharacteristicValueChange (options = {}) {
470
+ const BleManager = require('react-native-ble-manager').default
471
+ const { deviceId, serviceId, characteristicId, state = true, success = noop, fail = noop, complete = noop } = options
472
+
473
+ if (!deviceId || !serviceId || !characteristicId) {
474
+ const result = {
475
+ errMsg: 'notifyBLECharacteristicValueChange:ok',
476
+ errno: 1509000
477
+ }
478
+ success(result)
479
+ complete(result)
480
+ return
481
+ }
482
+
483
+ const subscriptionKey = `${deviceId}_${serviceId}_${characteristicId}`
484
+
485
+ if (state) {
486
+ // 启用监听
487
+ BleManager.startNotification(deviceId, serviceId, characteristicId).then(() => {
488
+ characteristicSubscriptions[subscriptionKey] = true
489
+
490
+ const result = {
491
+ errMsg: 'notifyBLECharacteristicValueChange:ok'
492
+ }
493
+ success(result)
494
+ complete(result)
495
+ }).catch((error) => {
496
+ const result = {
497
+ errMsg: 'notifyBLECharacteristicValueChange:fail ' + (typeof error === 'string' ? error : '')
498
+ }
499
+ fail(result)
500
+ complete(result)
501
+ })
502
+ } else {
503
+ // 停止监听
504
+ BleManager.stopNotification(deviceId, serviceId, characteristicId).then(() => {
505
+ delete characteristicSubscriptions[subscriptionKey]
506
+
507
+ const result = {
508
+ errMsg: 'notifyBLECharacteristicValueChange:ok'
509
+ }
510
+ success(result)
511
+ complete(result)
512
+ }).catch((error) => {
513
+ const result = {
514
+ errMsg: 'notifyBLECharacteristicValueChange:fail ' + (typeof error === 'string' ? error : '')
515
+ }
516
+ fail(result)
517
+ complete(result)
518
+ })
519
+ }
520
+ }
521
+
522
+ let valueForCharacteristicSubscriptions = null
523
+ function onBLECharacteristicValueChange (callback) {
524
+ const BleManager = require('react-native-ble-manager').default
525
+ if (characteristicCallbacks.length === 0) {
526
+ valueForCharacteristicSubscriptions = BleManager.onDidUpdateValueForCharacteristic((data) => {
527
+ // 将byte array转换为ArrayBuffer
528
+ const buffer = new ArrayBuffer(data.value.length)
529
+ const view = new Uint8Array(buffer)
530
+ data.value.forEach((byte, index) => {
531
+ view[index] = byte
532
+ })
533
+ const result = {
534
+ deviceId: data.peripheral,
535
+ serviceId: data.service,
536
+ characteristicId: data.characteristic,
537
+ value: buffer
538
+ }
539
+ characteristicCallbacks.forEach(cb => {
540
+ if (type(cb) === 'Function') {
541
+ cb(result)
542
+ }
543
+ })
544
+ })
545
+ }
546
+ if (characteristicCallbacks.indexOf(callback) === -1) {
547
+ characteristicCallbacks.push(callback)
548
+ }
549
+ }
550
+
551
+ function offBLECharacteristicValueChange (callback) {
552
+ const index = characteristicCallbacks.indexOf(callback)
553
+ if (index > -1) {
554
+ characteristicCallbacks.splice(index, 1)
555
+ }
556
+ if (characteristicCallbacks.length === 0 && valueForCharacteristicSubscriptions) {
557
+ valueForCharacteristicSubscriptions.remove()
558
+ valueForCharacteristicSubscriptions = null
559
+ }
560
+ }
561
+
562
+ function setBLEMTU (options = {}) {
563
+ const BleManager = require('react-native-ble-manager').default
564
+ const { deviceId, mtu, success = noop, fail = noop, complete = noop } = options
565
+ if (!mtu) {
566
+ commonFailHandler('setBLEMTU:fail parameter error: parameter.mtu should be Number instead of Undefined;', fail, complete)
567
+ return
568
+ }
569
+ if (!deviceId) {
570
+ commonFailHandler('setBLEMTU:fail parameter error: parameter.deviceId should be String instead of Undefined;', fail, complete)
571
+ return
572
+ }
573
+ if (!deviceId && !mtu) {
574
+ commonFailHandler('setBLEMTU:fail parameter error: parameter.deviceId should be String instead of Undefined;parameter.mtu should be Number instead of Undefined;', fail, complete)
575
+ return
576
+ }
577
+
578
+ BleManager.requestMTU(deviceId, mtu).then((actualMtu) => {
579
+ const result = {
580
+ errMsg: 'setBLEMTU:ok',
581
+ mtu: actualMtu
582
+ }
583
+ success(result)
584
+ complete(result)
585
+ }).catch((error) => {
586
+ const result = {
587
+ errMsg: 'setBLEMTU:fail ' + (typeof error === 'string' ? error : '')
588
+ }
589
+ fail(result)
590
+ complete(result)
591
+ })
592
+ }
593
+
594
+ function getBLEDeviceRSSI (options = {}) {
595
+ const BleManager = require('react-native-ble-manager').default
596
+ const { deviceId, success = noop, fail = noop, complete = noop } = options
597
+
598
+ if (!deviceId) {
599
+ const result = {
600
+ errMsg: 'getBLEDeviceRSSI:ok',
601
+ errno: 1509000
602
+ }
603
+ success(result)
604
+ complete(result)
605
+ return
606
+ }
607
+
608
+ BleManager.readRSSI(deviceId).then((rssi) => {
609
+ const result = {
610
+ errMsg: 'getBLEDeviceRSSI:ok',
611
+ RSSI: rssi
612
+ }
613
+ success(result)
614
+ complete(result)
615
+ }).catch((error) => {
616
+ const errmsg = typeof error === 'string' ? error : (typeof error === 'string' ? error : '')
617
+ const result = {
618
+ errMsg: 'getBLEDeviceRSSI:fail ' + errmsg
619
+ }
620
+ fail(result)
621
+ complete(result)
622
+ })
623
+ }
624
+
625
+ function getBLEDeviceServices (options = {}) {
626
+ const BleManager = require('react-native-ble-manager').default
627
+ const { deviceId, success = noop, fail = noop, complete = noop } = options
628
+
629
+ if (!deviceId) {
630
+ const result = {
631
+ errMsg: 'getBLEDeviceServices:ok',
632
+ errno: 1509000,
633
+ services: []
634
+ }
635
+ fail(result)
636
+ complete(result)
637
+ return
638
+ }
639
+ BleManager.retrieveServices(deviceId).then((peripheralInfo) => {
640
+ const services = peripheralInfo.services.map(service => ({
641
+ uuid: service.uuid,
642
+ isPrimary: true
643
+ }))
644
+
645
+ // 存储服务信息
646
+ BLEDeviceCharacteristics[deviceId] = peripheralInfo
647
+
648
+ const result = {
649
+ errMsg: 'getBLEDeviceServices:ok',
650
+ services: services
651
+ }
652
+ success(result)
653
+ complete(result)
654
+ }).catch((error) => {
655
+ const errmsg = typeof error === 'string' ? error : (typeof error === 'string' ? error : '')
656
+ const result = {
657
+ errMsg: 'getBLEDeviceServices:fail ' + errmsg
658
+ }
659
+ fail(result)
660
+ complete(result)
661
+ })
662
+ }
663
+
664
+ function getBLEDeviceCharacteristics (options = {}) {
665
+ const { deviceId, serviceId, success = noop, fail = noop, complete = noop } = options
666
+
667
+ if (!deviceId || !serviceId) {
668
+ const result = {
669
+ errMsg: 'getBLEDeviceCharacteristics:ok',
670
+ errno: 1509000,
671
+ characteristics: []
672
+ }
673
+ success(result)
674
+ complete(result)
675
+ return
676
+ }
677
+
678
+ const peripheralInfo = BLEDeviceCharacteristics[deviceId]
679
+ if (!peripheralInfo) {
680
+ const result = {
681
+ errMsg: 'getBLEDeviceCharacteristics:fail device services not retrieved'
682
+ }
683
+ fail(result)
684
+ complete(result)
685
+ return
686
+ }
687
+ const characteristicsList = peripheralInfo.characteristics || []
688
+ const service = characteristicsList.find(c => c.service.toLowerCase() === serviceId.toLowerCase())
689
+ if (!service && !characteristicsList.length) {
690
+ const result = {
691
+ errMsg: 'getBLEDeviceCharacteristics:fail service not found'
692
+ }
693
+ fail(result)
694
+ complete(result)
695
+ return
696
+ }
697
+ const characteristics = characteristicsList.map(char => ({
698
+ uuid: char.characteristic,
699
+ properties: {
700
+ read: !!char.properties.Read,
701
+ write: !!char.properties.Write,
702
+ notify: !!char.properties.Notify,
703
+ indicate: !!char.properties.Indicate,
704
+ writeNoResponse: !!char.properties.writeWithoutResponse
705
+ }
706
+ }))
707
+
708
+ const result = {
709
+ errMsg: 'getBLEDeviceCharacteristics:ok',
710
+ characteristics
711
+ }
712
+ success(result)
713
+ complete(result)
714
+ }
715
+
716
+ function createBLEConnection (options = {}) {
717
+ const BleManager = require('react-native-ble-manager').default
718
+ const { deviceId, timeout, success = noop, fail = noop, complete = noop } = options
719
+
720
+ if (!deviceId) {
721
+ const result = {
722
+ errMsg: 'createBLEConnection:ok',
723
+ errno: 1509000
724
+ }
725
+ fail(result)
726
+ complete(result)
727
+ return
728
+ }
729
+
730
+ BleManager.connect(deviceId, {
731
+ autoconnect: true
732
+ }).then(() => {
733
+ if (connectedDeviceId.indexOf(deviceId) === -1) {
734
+ connectedDeviceId.push(deviceId) // 记录一下已连接的设备id
735
+ }
736
+ clearTimeout(createBLEConnectionTimeout)
737
+ onBLEConnectionStateCallbacks.forEach(cb => {
738
+ if (type(cb) === 'Function') {
739
+ cb({
740
+ deviceId,
741
+ connected: true
742
+ })
743
+ }
744
+ })
745
+ connectedDevices.add(deviceId)
746
+ const result = {
747
+ errMsg: 'createBLEConnection:ok'
748
+ }
749
+ success(result)
750
+ complete(result)
751
+ }).catch((error) => {
752
+ clearTimeout(createBLEConnectionTimeout)
753
+ const result = {
754
+ errMsg: 'createBLEConnection:fail ' + (typeof error === 'string' ? error : '')
755
+ }
756
+ fail(result)
757
+ complete(result)
758
+ })
759
+ if (timeout) {
760
+ createBLEConnectionTimeout = setTimeout(() => { // 超时处理,仅ios会一直连接,android不会
761
+ BleManager.disconnect(deviceId).catch(() => {})
762
+ }, timeout)
763
+ }
764
+ }
765
+
766
+ function closeBLEConnection (options = {}) {
767
+ const BleManager = require('react-native-ble-manager').default
768
+ const { deviceId, success = noop, fail = noop, complete = noop } = options
769
+
770
+ if (!deviceId) {
771
+ const result = {
772
+ errMsg: 'closeBLEConnection:ok',
773
+ errno: 1509000
774
+ }
775
+ success(result)
776
+ complete(result)
777
+ return
778
+ }
779
+
780
+ BleManager.disconnect(deviceId).then(() => {
781
+ const index = connectedDeviceId.indexOf(deviceId)
782
+ if (index !== -1) {
783
+ connectedDeviceId.splice(index, 1) // 记录一下已连接的设备id
784
+ }
785
+ onBLEConnectionStateCallbacks.forEach(cb => {
786
+ if (type(cb) === 'Function') {
787
+ cb({
788
+ deviceId,
789
+ connected: false
790
+ })
791
+ }
792
+ })
793
+ connectedDevices.delete(deviceId)
794
+ const result = {
795
+ errMsg: 'closeBLEConnection:ok'
796
+ }
797
+ success(result)
798
+ complete(result)
799
+ }).catch((error) => {
800
+ const result = {
801
+ errMsg: 'closeBLEConnection:fail ' + (typeof error === 'string' ? error : '')
802
+ }
803
+ fail(result)
804
+ complete(result)
805
+ })
806
+ }
807
+
808
+ function onBLEConnectionStateChange (callback) {
809
+ if (!updateStateSubscription) {
810
+ onDidUpdateState()
811
+ }
812
+ if (onBLEConnectionStateCallbacks.indexOf(callback) === -1) {
813
+ onBLEConnectionStateCallbacks.push(callback)
814
+ }
815
+ }
816
+
817
+ function offBLEConnectionStateChange (callback) {
818
+ const index = onBLEConnectionStateCallbacks.indexOf(callback)
819
+ if (index !== -1) {
820
+ onBLEConnectionStateCallbacks.splice(index, 1)
821
+ }
822
+ if (onBLEConnectionStateCallbacks.length === 0) {
823
+ removeUpdateStateSubscription()
824
+ }
825
+ }
826
+
827
+ export {
828
+ openBluetoothAdapter,
829
+ closeBluetoothAdapter,
830
+ startBluetoothDevicesDiscovery,
831
+ stopBluetoothDevicesDiscovery,
832
+ onBluetoothDeviceFound,
833
+ offBluetoothDeviceFound,
834
+ getConnectedBluetoothDevices,
835
+ getBluetoothAdapterState,
836
+ onBluetoothAdapterStateChange,
837
+ offBluetoothAdapterStateChange,
838
+ getBluetoothDevices,
839
+ writeBLECharacteristicValue,
840
+ readBLECharacteristicValue,
841
+ notifyBLECharacteristicValueChange,
842
+ onBLECharacteristicValueChange,
843
+ offBLECharacteristicValueChange,
844
+ setBLEMTU,
845
+ getBLEDeviceRSSI,
846
+ getBLEDeviceServices,
847
+ getBLEDeviceCharacteristics,
848
+ createBLEConnection,
849
+ closeBLEConnection,
850
+ onBLEConnectionStateChange,
851
+ offBLEConnectionStateChange
852
+ }