@mpxjs/api-proxy 2.10.17 → 2.10.18
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.
- package/@types/index.d.ts +27 -0
- package/package.json +12 -4
- package/src/platform/api/base/index.ios.js +1 -0
- package/src/platform/api/base/index.web.js +1 -4
- package/src/platform/api/base/rnCanIUse.js +93 -0
- package/src/platform/api/base/rnCanIUseConfig.js +231 -0
- package/src/platform/api/ble-connection/index.ali.js +67 -2
- package/src/platform/api/ble-connection/index.ios.js +861 -0
- package/src/platform/api/ble-connection/index.js +65 -2
- package/src/platform/api/create-intersection-observer/rnIntersectionObserver.js +3 -0
- package/src/platform/api/device/wifi/index.ios.js +236 -0
- package/src/platform/api/device/wifi/index.js +22 -0
- package/src/platform/api/route/index.ios.js +13 -7
- package/src/platform/api/setting/index.ios.js +36 -0
- package/src/platform/index.js +3 -0
|
@@ -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
|
+
}
|