@onekeyfe/react-native-ble-utils 0.1.0 → 0.1.1
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/android/src/main/java/so/onekey/lib/ble/utils/BleUtilsModule.kt +216 -0
- package/android/src/main/java/so/onekey/lib/ble/utils/BleUtilsPackage.kt +17 -0
- package/android/src/main/java/so/onekey/lib/ble/utils/data/Peripheral.kt +35 -0
- package/package.json +9 -9
- /package/{lib → dist}/commonjs/index.js +0 -0
- /package/{lib → dist}/commonjs/index.js.map +0 -0
- /package/{lib → dist}/commonjs/type.js +0 -0
- /package/{lib → dist}/commonjs/type.js.map +0 -0
- /package/{lib → dist}/module/index.js +0 -0
- /package/{lib → dist}/module/index.js.map +0 -0
- /package/{lib → dist}/module/type.js +0 -0
- /package/{lib → dist}/module/type.js.map +0 -0
- /package/{lib → dist}/typescript/commonjs/package.json +0 -0
- /package/{lib → dist}/typescript/commonjs/src/index.d.ts +0 -0
- /package/{lib → dist}/typescript/commonjs/src/index.d.ts.map +0 -0
- /package/{lib → dist}/typescript/commonjs/src/type.d.ts +0 -0
- /package/{lib → dist}/typescript/commonjs/src/type.d.ts.map +0 -0
- /package/{lib → dist}/typescript/module/package.json +0 -0
- /package/{lib → dist}/typescript/module/src/index.d.ts +0 -0
- /package/{lib → dist}/typescript/module/src/index.d.ts.map +0 -0
- /package/{lib → dist}/typescript/module/src/type.d.ts +0 -0
- /package/{lib → dist}/typescript/module/src/type.d.ts.map +0 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
package so.onekey.lib.ble.utils
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.bluetooth.BluetoothAdapter
|
|
5
|
+
import android.bluetooth.BluetoothDevice
|
|
6
|
+
import android.bluetooth.BluetoothManager
|
|
7
|
+
import android.bluetooth.BluetoothProfile.GATT
|
|
8
|
+
import android.content.BroadcastReceiver
|
|
9
|
+
import android.content.Context
|
|
10
|
+
import android.content.Intent
|
|
11
|
+
import android.content.IntentFilter
|
|
12
|
+
import android.content.pm.PackageManager
|
|
13
|
+
import android.os.Build
|
|
14
|
+
import android.os.Handler
|
|
15
|
+
import android.os.Looper
|
|
16
|
+
import android.util.Log
|
|
17
|
+
import com.facebook.react.bridge.*
|
|
18
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
19
|
+
import so.onekey.lib.ble.utils.data.Peripheral
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class BleUtilsModule(private val reactContext: ReactApplicationContext) :
|
|
23
|
+
ReactContextBaseJavaModule(reactContext) {
|
|
24
|
+
|
|
25
|
+
private var bluetoothManager: BluetoothManager? = null
|
|
26
|
+
private val mBleBroadcastReceiver = lazy {
|
|
27
|
+
MyBroadcastReceiver(this)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
override fun getName() = NAME
|
|
31
|
+
|
|
32
|
+
private fun getBluetoothManager(): BluetoothManager? {
|
|
33
|
+
if (bluetoothManager == null) {
|
|
34
|
+
bluetoothManager =
|
|
35
|
+
reactContext.getSystemService(Context.BLUETOOTH_SERVICE)
|
|
36
|
+
}
|
|
37
|
+
return bluetoothManager
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private fun getBluetoothAdapter(): BluetoothAdapter? {
|
|
41
|
+
return getBluetoothManager()?.adapter
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
init {
|
|
45
|
+
registerBluetoothReceiver()
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private fun registerBluetoothReceiver() {
|
|
49
|
+
if (getBluetoothAdapter() == null) {
|
|
50
|
+
Log.d(LOG_TAG, "No bluetooth support")
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
val filter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
|
|
55
|
+
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED)
|
|
56
|
+
val intentFilter = IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST)
|
|
57
|
+
intentFilter.priority = IntentFilter.SYSTEM_HIGH_PRIORITY
|
|
58
|
+
if (Build.VERSION.SDK_INT >= 34) {
|
|
59
|
+
// Google in 2023 decides that flag RECEIVER_NOT_EXPORTED or RECEIVER_EXPORTED should be explicit set SDK 34(UPSIDE_DOWN_CAKE) on registering receivers.
|
|
60
|
+
// Also the export flags are available on Android 8 and higher, should be used with caution so that don't break compability with that devices.
|
|
61
|
+
reactContext.registerReceiver(mBleBroadcastReceiver.value, filter, Context.RECEIVER_EXPORTED)
|
|
62
|
+
reactContext.registerReceiver(
|
|
63
|
+
mBleBroadcastReceiver.value,
|
|
64
|
+
intentFilter,
|
|
65
|
+
Context.RECEIVER_EXPORTED
|
|
66
|
+
)
|
|
67
|
+
} else {
|
|
68
|
+
reactContext.registerReceiver(mBleBroadcastReceiver.value, filter)
|
|
69
|
+
reactContext.registerReceiver(mBleBroadcastReceiver.value, intentFilter)
|
|
70
|
+
}
|
|
71
|
+
Log.d(LOG_TAG, "BleManager initialized")
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 向JS端发送设备绑定状态变化事件
|
|
75
|
+
fun emitOnDeviceBondState(params: WritableMap) {
|
|
76
|
+
reactContext
|
|
77
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
78
|
+
.emit("onDeviceBondState", params)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// 事件监听管理
|
|
82
|
+
@ReactMethod
|
|
83
|
+
fun addListener(eventName: String) {
|
|
84
|
+
// 实现为空,仅用于满足RN事件监听器注册需求
|
|
85
|
+
Log.d(LOG_TAG, "addListener $eventName")
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@ReactMethod
|
|
89
|
+
fun removeListeners(count: Int) {
|
|
90
|
+
// 实现为空,仅用于满足RN事件监听器注册需求
|
|
91
|
+
Log.d(LOG_TAG, "removeListeners $count")
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@ReactMethod
|
|
95
|
+
fun checkState(callback: Callback) {
|
|
96
|
+
Log.d(LOG_TAG, "checkState")
|
|
97
|
+
|
|
98
|
+
val adapter = getBluetoothAdapter()
|
|
99
|
+
var state = "off"
|
|
100
|
+
if (!reactContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
|
|
101
|
+
state = "unsupported"
|
|
102
|
+
} else if (adapter != null) {
|
|
103
|
+
when (adapter.state) {
|
|
104
|
+
BluetoothAdapter.STATE_ON -> state = "on"
|
|
105
|
+
BluetoothAdapter.STATE_TURNING_ON -> state = "turning_on"
|
|
106
|
+
BluetoothAdapter.STATE_TURNING_OFF -> {
|
|
107
|
+
state = "turning_off"
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
BluetoothAdapter.STATE_OFF -> {
|
|
111
|
+
// should not happen as per https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#getState()
|
|
112
|
+
state = "off"
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
else -> {
|
|
116
|
+
state = "off"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
val map: WritableMap = Arguments.createMap()
|
|
122
|
+
map.putString("state", state)
|
|
123
|
+
Log.d(LOG_TAG, "state:$state")
|
|
124
|
+
callback.invoke(state)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@SuppressLint("MissingPermission")
|
|
128
|
+
@ReactMethod
|
|
129
|
+
fun getBondedPeripherals(callback: Callback) {
|
|
130
|
+
val map: WritableArray = Arguments.createArray()
|
|
131
|
+
val deviceSet: Set<BluetoothDevice> = getBluetoothAdapter()?.getBondedDevices() ?: emptySet()
|
|
132
|
+
for (device in deviceSet) {
|
|
133
|
+
val peripheral = Peripheral(device)
|
|
134
|
+
val jsonBundle: WritableMap = peripheral.asWritableMap()
|
|
135
|
+
map.pushMap(jsonBundle)
|
|
136
|
+
}
|
|
137
|
+
callback.invoke(null, map)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@SuppressLint("MissingPermission")
|
|
141
|
+
@ReactMethod
|
|
142
|
+
fun getConnectedPeripherals(serviceUUIDs: ReadableArray?, callback: Callback) {
|
|
143
|
+
Log.d(LOG_TAG, "Get connected peripherals")
|
|
144
|
+
val map: WritableArray = Arguments.createArray()
|
|
145
|
+
|
|
146
|
+
if (getBluetoothAdapter() == null) {
|
|
147
|
+
Log.d(LOG_TAG, "No bluetooth support")
|
|
148
|
+
callback.invoke("No bluetooth support")
|
|
149
|
+
return
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
val peripherals: List<BluetoothDevice> =
|
|
153
|
+
getBluetoothManager()?.getConnectedDevices(GATT) ?: emptyList()
|
|
154
|
+
for (entry in peripherals) {
|
|
155
|
+
val peripheral = Peripheral(entry)
|
|
156
|
+
val jsonBundle: WritableMap = peripheral.asWritableMap()
|
|
157
|
+
map.pushMap(jsonBundle)
|
|
158
|
+
}
|
|
159
|
+
callback.invoke(null, map)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private class MyBroadcastReceiver(private val module: BleUtilsModule) : BroadcastReceiver() {
|
|
163
|
+
@SuppressLint("MissingPermission")
|
|
164
|
+
override fun onReceive(context: Context, intent: Intent) {
|
|
165
|
+
Log.d(LOG_TAG, "onReceive")
|
|
166
|
+
val action = intent.action
|
|
167
|
+
|
|
168
|
+
if (action == BluetoothDevice.ACTION_BOND_STATE_CHANGED) {
|
|
169
|
+
val bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR)
|
|
170
|
+
val prevState = intent.getIntExtra(
|
|
171
|
+
BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR
|
|
172
|
+
)
|
|
173
|
+
val device = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
174
|
+
intent.getParcelableExtra(
|
|
175
|
+
BluetoothDevice.EXTRA_DEVICE, BluetoothDevice::class.java
|
|
176
|
+
)
|
|
177
|
+
} else {
|
|
178
|
+
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
var bondStateStr = "UNKNOWN"
|
|
182
|
+
when (bondState) {
|
|
183
|
+
BluetoothDevice.BOND_BONDED -> bondStateStr = "BOND_BONDED"
|
|
184
|
+
BluetoothDevice.BOND_BONDING -> bondStateStr = "BOND_BONDING"
|
|
185
|
+
BluetoothDevice.BOND_NONE -> bondStateStr = "BOND_NONE"
|
|
186
|
+
BluetoothDevice.ERROR -> bondStateStr = "BOND_ERROR"
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
var prevBondStateStr = "UNKNOWN"
|
|
190
|
+
when (prevState) {
|
|
191
|
+
BluetoothDevice.BOND_BONDED -> prevBondStateStr = "BOND_BONDED"
|
|
192
|
+
BluetoothDevice.BOND_BONDING -> prevBondStateStr = "BOND_BONDING"
|
|
193
|
+
BluetoothDevice.BOND_NONE -> prevBondStateStr = "BOND_NONE"
|
|
194
|
+
BluetoothDevice.ERROR -> bondStateStr = "BOND_ERROR"
|
|
195
|
+
}
|
|
196
|
+
Log.d(LOG_TAG, "bond state: $bondStateStr")
|
|
197
|
+
Log.d(LOG_TAG, "bond state: $prevBondStateStr")
|
|
198
|
+
|
|
199
|
+
val bond = Arguments.createMap()
|
|
200
|
+
bond.putString("state", bondStateStr)
|
|
201
|
+
bond.putString("preState", prevBondStateStr)
|
|
202
|
+
|
|
203
|
+
val peripheral = Peripheral(device!!)
|
|
204
|
+
val map = peripheral.asWritableMap()
|
|
205
|
+
map.putMap("bondState", bond)
|
|
206
|
+
Log.d(LOG_TAG, "onReceive BluetoothDevice BondState Change ${map}")
|
|
207
|
+
module.emitOnDeviceBondState(map)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
companion object {
|
|
213
|
+
const val NAME = "BleUtilsModule"
|
|
214
|
+
const val LOG_TAG: String = "RNBleUtils"
|
|
215
|
+
}
|
|
216
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
package so.onekey.lib.ble.utils
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BleUtilsPackage : ReactPackage {
|
|
10
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
11
|
+
return listOf(BleUtilsModule(reactContext))
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
15
|
+
return emptyList()
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
package so.onekey.lib.ble.utils.data
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.bluetooth.BluetoothDevice
|
|
5
|
+
import android.util.Log
|
|
6
|
+
import com.facebook.react.bridge.Arguments
|
|
7
|
+
import com.facebook.react.bridge.WritableMap
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Peripheral(
|
|
11
|
+
private val device: BluetoothDevice
|
|
12
|
+
) {
|
|
13
|
+
@SuppressLint("MissingPermission")
|
|
14
|
+
fun asWritableMap(): WritableMap {
|
|
15
|
+
val map: WritableMap = Arguments.createMap()
|
|
16
|
+
val advertising: WritableMap = Arguments.createMap()
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
map.putString("name", device.getName())
|
|
20
|
+
map.putString("id", device.getAddress()) // mac address
|
|
21
|
+
|
|
22
|
+
val name: String = device.getName()
|
|
23
|
+
if (name != null) advertising.putString("localName", name)
|
|
24
|
+
|
|
25
|
+
// No scanResult to access so we can't check if peripheral is connectable
|
|
26
|
+
advertising.putBoolean("isConnectable", true)
|
|
27
|
+
|
|
28
|
+
map.putMap("advertising", advertising)
|
|
29
|
+
} catch (e: Exception) { // this shouldn't happen
|
|
30
|
+
Log.e("BleUtils", "Unexpected error on asWritableMap", e)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return map
|
|
34
|
+
}
|
|
35
|
+
}
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/react-native-ble-utils",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "ble uilts",
|
|
5
5
|
"source": "./src/index.tsx",
|
|
6
|
-
"main": "./
|
|
7
|
-
"module": "./
|
|
6
|
+
"main": "./dist/commonjs/index.js",
|
|
7
|
+
"module": "./dist/module/index.js",
|
|
8
8
|
"react-native": "src/index.ts",
|
|
9
|
-
"types": "./
|
|
9
|
+
"types": "./dist/typescript/module/src/index.d.ts",
|
|
10
10
|
"files": [
|
|
11
11
|
"src",
|
|
12
|
-
"
|
|
12
|
+
"dist",
|
|
13
13
|
"android",
|
|
14
14
|
"ios",
|
|
15
15
|
"cpp",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"test": "jest",
|
|
32
32
|
"typecheck": "tsc",
|
|
33
33
|
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
34
|
-
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build
|
|
34
|
+
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build dist",
|
|
35
35
|
"prepare": "bob build",
|
|
36
36
|
"release": "release-it"
|
|
37
37
|
},
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"preset": "react-native",
|
|
91
91
|
"modulePathIgnorePatterns": [
|
|
92
92
|
"<rootDir>/example/node_modules",
|
|
93
|
-
"<rootDir>/
|
|
93
|
+
"<rootDir>/dist/"
|
|
94
94
|
]
|
|
95
95
|
},
|
|
96
96
|
"commitlint": {
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
},
|
|
138
138
|
"eslintIgnore": [
|
|
139
139
|
"node_modules/",
|
|
140
|
-
"
|
|
140
|
+
"dist/"
|
|
141
141
|
],
|
|
142
142
|
"prettier": {
|
|
143
143
|
"quoteProps": "consistent",
|
|
@@ -148,7 +148,7 @@
|
|
|
148
148
|
},
|
|
149
149
|
"react-native-builder-bob": {
|
|
150
150
|
"source": "src",
|
|
151
|
-
"output": "
|
|
151
|
+
"output": "dist",
|
|
152
152
|
"targets": [
|
|
153
153
|
[
|
|
154
154
|
"commonjs",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|