@mpxjs/api-proxy 2.10.17-beta.1 → 2.10.17-beta.13

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,861 @@
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 && Object.values(advertising.manufacturerData)[0]?.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,
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
+ if (device.name) {
217
+ getDevices.splice(existingDeviceIndex, 1, deviceInfo)
218
+ }
219
+ return
220
+ }
221
+ }
222
+ deviceFoundCallbacks.forEach(cb => {
223
+ if (type(cb) === 'Function') {
224
+ cb({
225
+ devices: [deviceInfo]
226
+ })
227
+ }
228
+ })
229
+ getDevices.push(deviceInfo)
230
+ // 处理设备发现逻辑
231
+ })
232
+ BleManager.scan(services, 0, allowDuplicatesKey).then((res) => { // 必须,没有开启扫描,onDiscoverPeripheral回调不会触发
233
+ onStateChangeCallbacks.forEach(cb => {
234
+ if (type(cb) === 'Function') {
235
+ cb({
236
+ available: true,
237
+ discovering: true
238
+ })
239
+ }
240
+ })
241
+ discovering = true
242
+ getDevices = [] // 清空之前的发现设备列表
243
+ const result = {
244
+ errMsg: 'startBluetoothDevicesDiscovery:ok',
245
+ isDiscovering: true
246
+ }
247
+ success(result)
248
+ complete(result)
249
+ }).catch((error) => {
250
+ commonFailHandler('startBluetoothDevicesDiscovery:fail ' + (typeof error === 'string' ? error : ''), fail, complete)
251
+ })
252
+ }
253
+
254
+ function stopBluetoothDevicesDiscovery (options = {}) {
255
+ const BleManager = require('react-native-ble-manager').default
256
+ const { success = noop, fail = noop, complete = noop } = options
257
+
258
+ if (!bleManagerInitialized) {
259
+ commonFailHandler('stopBluetoothDevicesDiscovery:fail ble adapter hans\'t been opened or ble is unavailable.', fail, complete)
260
+ return
261
+ }
262
+ removeBluetoothDevicesDiscovery()
263
+ BleManager.stopScan().then(() => {
264
+ discovering = false
265
+ onStateChangeCallbacks.forEach(cb => {
266
+ if (type(cb) === 'Function') {
267
+ cb({
268
+ available: true,
269
+ discovering: false
270
+ })
271
+ }
272
+ })
273
+ const result = {
274
+ errMsg: 'stopBluetoothDevicesDiscovery:ok'
275
+ }
276
+ success(result)
277
+ complete(result)
278
+ }).catch((error) => {
279
+ commonFailHandler('stopBluetoothDevicesDiscovery:fail ' + (typeof error === 'string' ? error : ''), fail, complete)
280
+ })
281
+ }
282
+
283
+ function onBluetoothDeviceFound (callback) {
284
+ if (deviceFoundCallbacks.indexOf(callback) === -1) {
285
+ deviceFoundCallbacks.push(callback)
286
+ }
287
+ }
288
+
289
+ function offBluetoothDeviceFound (callback) {
290
+ const index = deviceFoundCallbacks.indexOf(callback)
291
+ if (index > -1) {
292
+ deviceFoundCallbacks.splice(index, 1)
293
+ }
294
+ }
295
+
296
+ function getConnectedBluetoothDevices (options = {}) {
297
+ const BleManager = require('react-native-ble-manager').default
298
+ const { services = [], success = noop, fail = noop, complete = noop } = options
299
+
300
+ if (!bleManagerInitialized) {
301
+ commonFailHandler('getConnectedBluetoothDevices:fail 请先调用 wx.openBluetoothAdapter 接口进行初始化操作', fail, complete)
302
+ return
303
+ }
304
+
305
+ BleManager.getConnectedPeripherals(services).then((peripherals) => {
306
+ const devices = peripherals.map(peripheral => ({
307
+ deviceId: peripheral.id,
308
+ name: peripheral.name || '未知设备'
309
+ }))
310
+ const result = {
311
+ errMsg: 'getConnectedBluetoothDevices:ok',
312
+ devices: devices
313
+ }
314
+ success(result)
315
+ complete(result)
316
+ }).catch((error) => {
317
+ commonFailHandler('getConnectedBluetoothDevices:fail ' + (typeof error === 'string' ? error : ''), fail, complete)
318
+ })
319
+ }
320
+
321
+ function getBluetoothAdapterState (options = {}) {
322
+ const BleManager = require('react-native-ble-manager').default
323
+ const { success = noop, fail = noop, complete = noop } = options
324
+
325
+ if (!bleManagerInitialized) {
326
+ commonFailHandler('getBluetoothAdapterState:fail ble adapter need open first.', fail, complete)
327
+ return
328
+ }
329
+
330
+ BleManager.checkState().then((state) => {
331
+ const result = {
332
+ errMsg: 'getBluetoothAdapterState:ok',
333
+ discovering,
334
+ available: state === 'on'
335
+ }
336
+ success(result)
337
+ complete(result)
338
+ }).catch((error) => {
339
+ commonFailHandler('getBluetoothAdapterState:fail ' + (typeof error === 'string' ? error : ''), fail, complete)
340
+ })
341
+ }
342
+ function onDidUpdateState () {
343
+ const BleManager = require('react-native-ble-manager').default
344
+ updateStateSubscription = BleManager.onDidUpdateState((state) => {
345
+ onStateChangeCallbacks.forEach(cb => {
346
+ if (type(cb) === 'Function') {
347
+ cb({
348
+ available: state.state === 'on',
349
+ discovering: state.state === 'on' ? discovering : false
350
+ })
351
+ }
352
+ })
353
+ if (onBLEConnectionStateCallbacks.length && connectedDeviceId.length && state.state !== 'on') {
354
+ connectedDeviceId.forEach((id) => {
355
+ onBLEConnectionStateCallbacks.forEach(cb => {
356
+ if (type(cb) === 'Function') {
357
+ cb({
358
+ deviceId: id,
359
+ connected: false
360
+ })
361
+ }
362
+ })
363
+ })
364
+ }
365
+ })
366
+ }
367
+
368
+ function onBluetoothAdapterStateChange (callback) {
369
+ if (!updateStateSubscription) {
370
+ onDidUpdateState()
371
+ }
372
+ if (onStateChangeCallbacks.indexOf(callback) === -1) {
373
+ onStateChangeCallbacks.push(callback)
374
+ }
375
+ }
376
+
377
+ function offBluetoothAdapterStateChange (callback) {
378
+ const index = onStateChangeCallbacks.indexOf(callback)
379
+ if (index > -1) {
380
+ onStateChangeCallbacks.splice(index, 1)
381
+ }
382
+ if (deviceFoundCallbacks.length === 0) {
383
+ removeUpdateStateSubscription()
384
+ }
385
+ }
386
+
387
+ function getBluetoothDevices (options = {}) { // 该能力只是获取应用级别已连接设备列表,非手机级别的已连接设备列表
388
+ const { success = noop, fail = noop, complete = noop } = options
389
+ if (!bleManagerInitialized) {
390
+ const result = {
391
+ errMsg: 'getBluetoothDevices:fail ble adapter hans\'t been opened or ble is unavailable.'
392
+ }
393
+ fail(result)
394
+ complete(result)
395
+ return
396
+ }
397
+ const result = {
398
+ errMsg: 'getBluetoothDevices:ok',
399
+ devices: getDevices // 返回已扫描的设备列表
400
+ }
401
+ success(result)
402
+ complete(result)
403
+ }
404
+
405
+ function writeBLECharacteristicValue (options = {}) {
406
+ const BleManager = require('react-native-ble-manager').default
407
+ const { deviceId, serviceId, characteristicId, value, writeType, success = noop, fail = noop, complete = noop } = options
408
+ if (!deviceId || !serviceId || !characteristicId || !value) {
409
+ const result = {
410
+ errMsg: 'writeBLECharacteristicValue:fail parameter error',
411
+ errno: 1001
412
+ }
413
+ success(result)
414
+ fail(result)
415
+ return
416
+ }
417
+ let writeTypeValue = writeType
418
+ if (!writeType) {
419
+ // 与小程序拉齐 iOS 未传值的情况优先 write,安卓优先 writeNoResponse 。
420
+ writeTypeValue = __mpx_mode__ === 'ios' ? 'write' : 'writeNoResponse'
421
+ }
422
+ // 将ArrayBuffer转换为byte array
423
+ const bytes = Array.from(new Uint8Array(value))
424
+ const writeMethod = writeTypeValue === 'writeNoResponse'
425
+ ? BleManager.writeWithoutResponse(deviceId, serviceId, characteristicId, bytes)
426
+ : BleManager.write(deviceId, serviceId, characteristicId, bytes)
427
+ writeMethod.then(() => {
428
+ const result = {
429
+ errMsg: 'writeBLECharacteristicValue:ok'
430
+ }
431
+ success(result)
432
+ complete(result)
433
+ }).catch((error) => {
434
+ const result = {
435
+ errMsg: 'writeBLECharacteristicValue:fail ' + (typeof error === 'string' ? error : '')
436
+ }
437
+ fail(result)
438
+ complete(result)
439
+ })
440
+ }
441
+
442
+ function readBLECharacteristicValue (options = {}) {
443
+ const BleManager = require('react-native-ble-manager').default
444
+ const { deviceId, serviceId, characteristicId, success = noop, fail = noop, complete = noop } = options
445
+
446
+ if (!deviceId || !serviceId || !characteristicId) {
447
+ const result = {
448
+ errMsg: 'readBLECharacteristicValue:ok',
449
+ errno: 1509000
450
+ }
451
+ success(result)
452
+ complete(result)
453
+ return
454
+ }
455
+
456
+ BleManager.read(deviceId, serviceId, characteristicId).then((data) => {
457
+ // 将byte array转换为ArrayBuffer
458
+ const buffer = new ArrayBuffer(data.length)
459
+ const view = new Uint8Array(buffer)
460
+ data.forEach((byte, index) => {
461
+ view[index] = byte
462
+ })
463
+
464
+ const result = {
465
+ errMsg: 'readBLECharacteristicValue:ok',
466
+ value: buffer
467
+ }
468
+ success(result)
469
+ complete(result)
470
+ }).catch((error) => {
471
+ const result = {
472
+ errMsg: 'readBLECharacteristicValue:fail ' + (typeof error === 'string' ? error : '')
473
+ }
474
+ fail(result)
475
+ complete(result)
476
+ })
477
+ }
478
+
479
+ function notifyBLECharacteristicValueChange (options = {}) {
480
+ const BleManager = require('react-native-ble-manager').default
481
+ const { deviceId, serviceId, characteristicId, state = true, success = noop, fail = noop, complete = noop } = options
482
+
483
+ if (!deviceId || !serviceId || !characteristicId) {
484
+ const result = {
485
+ errMsg: 'notifyBLECharacteristicValueChange:ok',
486
+ errno: 1509000
487
+ }
488
+ success(result)
489
+ complete(result)
490
+ return
491
+ }
492
+
493
+ const subscriptionKey = `${deviceId}_${serviceId}_${characteristicId}`
494
+
495
+ if (state) {
496
+ // 启用监听
497
+ BleManager.startNotification(deviceId, serviceId, characteristicId).then(() => {
498
+ characteristicSubscriptions[subscriptionKey] = true
499
+
500
+ const result = {
501
+ errMsg: 'notifyBLECharacteristicValueChange:ok'
502
+ }
503
+ success(result)
504
+ complete(result)
505
+ }).catch((error) => {
506
+ const result = {
507
+ errMsg: 'notifyBLECharacteristicValueChange:fail ' + (typeof error === 'string' ? error : '')
508
+ }
509
+ fail(result)
510
+ complete(result)
511
+ })
512
+ } else {
513
+ // 停止监听
514
+ BleManager.stopNotification(deviceId, serviceId, characteristicId).then(() => {
515
+ delete characteristicSubscriptions[subscriptionKey]
516
+
517
+ const result = {
518
+ errMsg: 'notifyBLECharacteristicValueChange:ok'
519
+ }
520
+ success(result)
521
+ complete(result)
522
+ }).catch((error) => {
523
+ const result = {
524
+ errMsg: 'notifyBLECharacteristicValueChange:fail ' + (typeof error === 'string' ? error : '')
525
+ }
526
+ fail(result)
527
+ complete(result)
528
+ })
529
+ }
530
+ }
531
+
532
+ let valueForCharacteristicSubscriptions = null
533
+ function onBLECharacteristicValueChange (callback) {
534
+ const BleManager = require('react-native-ble-manager').default
535
+ if (characteristicCallbacks.length === 0) {
536
+ valueForCharacteristicSubscriptions = BleManager.onDidUpdateValueForCharacteristic((data) => {
537
+ // 将byte array转换为ArrayBuffer
538
+ const buffer = new ArrayBuffer(data.value.length)
539
+ const view = new Uint8Array(buffer)
540
+ data.value.forEach((byte, index) => {
541
+ view[index] = byte
542
+ })
543
+ const result = {
544
+ deviceId: data.peripheral,
545
+ serviceId: data.service,
546
+ characteristicId: data.characteristic,
547
+ value: buffer
548
+ }
549
+ characteristicCallbacks.forEach(cb => {
550
+ if (type(cb) === 'Function') {
551
+ cb(result)
552
+ }
553
+ })
554
+ })
555
+ }
556
+ if (characteristicCallbacks.indexOf(callback) === -1) {
557
+ characteristicCallbacks.push(callback)
558
+ }
559
+ }
560
+
561
+ function offBLECharacteristicValueChange (callback) {
562
+ const index = characteristicCallbacks.indexOf(callback)
563
+ if (index > -1) {
564
+ characteristicCallbacks.splice(index, 1)
565
+ }
566
+ if (characteristicCallbacks.length === 0 && valueForCharacteristicSubscriptions) {
567
+ valueForCharacteristicSubscriptions.remove()
568
+ valueForCharacteristicSubscriptions = null
569
+ }
570
+ }
571
+
572
+ function setBLEMTU (options = {}) {
573
+ const BleManager = require('react-native-ble-manager').default
574
+ const { deviceId, mtu, success = noop, fail = noop, complete = noop } = options
575
+ if (!mtu) {
576
+ commonFailHandler('setBLEMTU:fail parameter error: parameter.mtu should be Number instead of Undefined;', fail, complete)
577
+ return
578
+ }
579
+ if (!deviceId) {
580
+ commonFailHandler('setBLEMTU:fail parameter error: parameter.deviceId should be String instead of Undefined;', fail, complete)
581
+ return
582
+ }
583
+ if (!deviceId && !mtu) {
584
+ commonFailHandler('setBLEMTU:fail parameter error: parameter.deviceId should be String instead of Undefined;parameter.mtu should be Number instead of Undefined;', fail, complete)
585
+ return
586
+ }
587
+
588
+ BleManager.requestMTU(deviceId, mtu).then((actualMtu) => {
589
+ const result = {
590
+ errMsg: 'setBLEMTU:ok',
591
+ mtu: actualMtu
592
+ }
593
+ success(result)
594
+ complete(result)
595
+ }).catch((error) => {
596
+ const result = {
597
+ errMsg: 'setBLEMTU:fail ' + (typeof error === 'string' ? error : '')
598
+ }
599
+ fail(result)
600
+ complete(result)
601
+ })
602
+ }
603
+
604
+ function getBLEDeviceRSSI (options = {}) {
605
+ const BleManager = require('react-native-ble-manager').default
606
+ const { deviceId, success = noop, fail = noop, complete = noop } = options
607
+
608
+ if (!deviceId) {
609
+ const result = {
610
+ errMsg: 'getBLEDeviceRSSI:ok',
611
+ errno: 1509000
612
+ }
613
+ success(result)
614
+ complete(result)
615
+ return
616
+ }
617
+
618
+ BleManager.readRSSI(deviceId).then((rssi) => {
619
+ const result = {
620
+ errMsg: 'getBLEDeviceRSSI:ok',
621
+ RSSI: rssi
622
+ }
623
+ success(result)
624
+ complete(result)
625
+ }).catch((error) => {
626
+ const errmsg = typeof error === 'string' ? error : (typeof error === 'string' ? error : '')
627
+ const result = {
628
+ errMsg: 'getBLEDeviceRSSI:fail ' + errmsg
629
+ }
630
+ fail(result)
631
+ complete(result)
632
+ })
633
+ }
634
+
635
+ function getBLEDeviceServices (options = {}) {
636
+ const BleManager = require('react-native-ble-manager').default
637
+ const { deviceId, success = noop, fail = noop, complete = noop } = options
638
+
639
+ if (!deviceId) {
640
+ const result = {
641
+ errMsg: 'getBLEDeviceServices:ok',
642
+ errno: 1509000,
643
+ services: []
644
+ }
645
+ fail(result)
646
+ complete(result)
647
+ return
648
+ }
649
+ BleManager.retrieveServices(deviceId).then((peripheralInfo) => {
650
+ const services = peripheralInfo.services.map(service => ({
651
+ uuid: service.uuid
652
+ }))
653
+
654
+ // 存储服务信息
655
+ BLEDeviceCharacteristics[deviceId] = peripheralInfo
656
+
657
+ const result = {
658
+ errMsg: 'getBLEDeviceServices:ok',
659
+ services: services
660
+ }
661
+ success(result)
662
+ complete(result)
663
+ }).catch((error) => {
664
+ const errmsg = typeof error === 'string' ? error : (typeof error === 'string' ? error : '')
665
+ const result = {
666
+ errMsg: 'getBLEDeviceServices:fail ' + errmsg
667
+ }
668
+ fail(result)
669
+ complete(result)
670
+ })
671
+ }
672
+
673
+ function getBLEDeviceCharacteristics (options = {}) {
674
+ const { deviceId, serviceId, success = noop, fail = noop, complete = noop } = options
675
+
676
+ if (!deviceId || !serviceId) {
677
+ const result = {
678
+ errMsg: 'getBLEDeviceCharacteristics:ok',
679
+ errno: 1509000,
680
+ characteristics: []
681
+ }
682
+ success(result)
683
+ complete(result)
684
+ return
685
+ }
686
+
687
+ const peripheralInfo = BLEDeviceCharacteristics[deviceId]
688
+ if (!peripheralInfo) {
689
+ const result = {
690
+ errMsg: 'getBLEDeviceCharacteristics:fail device services not retrieved'
691
+ }
692
+ fail(result)
693
+ complete(result)
694
+ return
695
+ }
696
+ const characteristicsList = peripheralInfo.characteristics || []
697
+ const service = characteristicsList.find(c => c.service.toLowerCase() === serviceId.toLowerCase())
698
+ if (!service && !characteristicsList.length) {
699
+ const result = {
700
+ errMsg: 'getBLEDeviceCharacteristics:fail service not found'
701
+ }
702
+ fail(result)
703
+ complete(result)
704
+ return
705
+ }
706
+ const characteristics = characteristicsList.map(char => ({
707
+ uuid: char.characteristic,
708
+ properties: {
709
+ read: !!char.properties.Read,
710
+ write: !!char.properties.Write,
711
+ notify: !!char.properties.Notify,
712
+ indicate: !!char.properties.Indicate,
713
+ writeNoResponse: !!char.properties.WriteWithoutResponse
714
+ }
715
+ }))
716
+
717
+ const result = {
718
+ errMsg: 'getBLEDeviceCharacteristics:ok',
719
+ characteristics
720
+ }
721
+ success(result)
722
+ complete(result)
723
+ }
724
+
725
+ function createBLEConnection (options = {}) {
726
+ const BleManager = require('react-native-ble-manager').default
727
+ const { deviceId, timeout, success = noop, fail = noop, complete = noop } = options
728
+
729
+ if (!deviceId) {
730
+ const result = {
731
+ errMsg: 'createBLEConnection:ok',
732
+ errno: 1509000
733
+ }
734
+ fail(result)
735
+ complete(result)
736
+ return
737
+ }
738
+
739
+ BleManager.connect(deviceId, {
740
+ autoconnect: true
741
+ }).then(() => {
742
+ if (connectedDeviceId.indexOf(deviceId) === -1) {
743
+ connectedDeviceId.push(deviceId) // 记录一下已连接的设备id
744
+ }
745
+ clearTimeout(createBLEConnectionTimeout)
746
+ onBLEConnectionStateCallbacks.forEach(cb => {
747
+ if (type(cb) === 'Function') {
748
+ cb({
749
+ deviceId,
750
+ connected: true
751
+ })
752
+ }
753
+ })
754
+ connectedDevices.add(deviceId)
755
+ const result = {
756
+ errMsg: 'createBLEConnection:ok'
757
+ }
758
+ success(result)
759
+ complete(result)
760
+ }).catch((error) => {
761
+ clearTimeout(createBLEConnectionTimeout)
762
+ const result = {
763
+ errMsg: 'createBLEConnection:fail ' + (typeof error === 'string' ? error : '')
764
+ }
765
+ fail(result)
766
+ complete(result)
767
+ })
768
+ if (timeout) {
769
+ createBLEConnectionTimeout = setTimeout(() => { // 超时处理,仅ios会一直连接,android不会
770
+ BleManager.disconnect(deviceId).catch(() => {})
771
+ }, timeout)
772
+ }
773
+ }
774
+
775
+ function closeBLEConnection (options = {}) {
776
+ const BleManager = require('react-native-ble-manager').default
777
+ const { deviceId, success = noop, fail = noop, complete = noop } = options
778
+
779
+ if (!deviceId) {
780
+ const result = {
781
+ errMsg: 'closeBLEConnection:ok',
782
+ errno: 1509000
783
+ }
784
+ success(result)
785
+ complete(result)
786
+ return
787
+ }
788
+
789
+ BleManager.disconnect(deviceId).then(() => {
790
+ const index = connectedDeviceId.indexOf(deviceId)
791
+ if (index !== -1) {
792
+ connectedDeviceId.splice(index, 1) // 记录一下已连接的设备id
793
+ }
794
+ onBLEConnectionStateCallbacks.forEach(cb => {
795
+ if (type(cb) === 'Function') {
796
+ cb({
797
+ deviceId,
798
+ connected: false
799
+ })
800
+ }
801
+ })
802
+ connectedDevices.delete(deviceId)
803
+ const result = {
804
+ errMsg: 'closeBLEConnection:ok'
805
+ }
806
+ success(result)
807
+ complete(result)
808
+ }).catch((error) => {
809
+ const result = {
810
+ errMsg: 'closeBLEConnection:fail ' + (typeof error === 'string' ? error : '')
811
+ }
812
+ fail(result)
813
+ complete(result)
814
+ })
815
+ }
816
+
817
+ function onBLEConnectionStateChange (callback) {
818
+ if (!updateStateSubscription) {
819
+ onDidUpdateState()
820
+ }
821
+ if (onBLEConnectionStateCallbacks.indexOf(callback) === -1) {
822
+ onBLEConnectionStateCallbacks.push(callback)
823
+ }
824
+ }
825
+
826
+ function offBLEConnectionStateChange (callback) {
827
+ const index = onBLEConnectionStateCallbacks.indexOf(callback)
828
+ if (index !== -1) {
829
+ onBLEConnectionStateCallbacks.splice(index, 1)
830
+ }
831
+ if (onBLEConnectionStateCallbacks.length === 0) {
832
+ removeUpdateStateSubscription()
833
+ }
834
+ }
835
+
836
+ export {
837
+ openBluetoothAdapter,
838
+ closeBluetoothAdapter,
839
+ startBluetoothDevicesDiscovery,
840
+ stopBluetoothDevicesDiscovery,
841
+ onBluetoothDeviceFound,
842
+ offBluetoothDeviceFound,
843
+ getConnectedBluetoothDevices,
844
+ getBluetoothAdapterState,
845
+ onBluetoothAdapterStateChange,
846
+ offBluetoothAdapterStateChange,
847
+ getBluetoothDevices,
848
+ writeBLECharacteristicValue,
849
+ readBLECharacteristicValue,
850
+ notifyBLECharacteristicValueChange,
851
+ onBLECharacteristicValueChange,
852
+ offBLECharacteristicValueChange,
853
+ setBLEMTU,
854
+ getBLEDeviceRSSI,
855
+ getBLEDeviceServices,
856
+ getBLEDeviceCharacteristics,
857
+ createBLEConnection,
858
+ closeBLEConnection,
859
+ onBLEConnectionStateChange,
860
+ offBLEConnectionStateChange
861
+ }