From 328b1b69a5e890b451c9863bf46243ca592175d3 Mon Sep 17 00:00:00 2001 From: ByteZhang Date: Fri, 3 Jul 2026 23:54:45 +0800 Subject: [PATCH] fix(android): keep connected BLE devices with uncached service UUIDs getConnectedPeripherals filters by serviceUUIDs but treats a null/empty device.uuids as unknown (keep), not absent (drop), so bonded OneKey devices whose GATT services aren't cached in getUuids() aren't lost on some ROMs. Also exposes serviceUUIDs on peripherals. Bump 0.1.6. --- .../so/onekey/lib/ble/utils/BleUtilsModule.kt | 20 +++++++++++++++++++ .../onekey/lib/ble/utils/data/Peripheral.kt | 4 ++++ package.json | 2 +- src/index.ts | 2 +- src/type.ts | 1 + 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/android/src/main/java/so/onekey/lib/ble/utils/BleUtilsModule.kt b/android/src/main/java/so/onekey/lib/ble/utils/BleUtilsModule.kt index a07115f..bbf63f9 100644 --- a/android/src/main/java/so/onekey/lib/ble/utils/BleUtilsModule.kt +++ b/android/src/main/java/so/onekey/lib/ble/utils/BleUtilsModule.kt @@ -192,9 +192,19 @@ class BleUtilsModule(private val reactContext: ReactApplicationContext) : return } + val wantedServiceUuids = HashSet() + if (serviceUUIDs != null) { + for (i in 0 until serviceUUIDs.size()) { + serviceUUIDs.getString(i)?.let { wantedServiceUuids.add(it.lowercase()) } + } + } + val peripherals: List = getBluetoothManager()?.getConnectedDevices(GATT) ?: emptyList() for (entry in peripherals) { + if (wantedServiceUuids.isNotEmpty() && !deviceExposesService(entry, wantedServiceUuids)) { + continue + } val peripheral = Peripheral(entry) val jsonBundle: WritableMap = peripheral.asWritableMap() map.pushMap(jsonBundle) @@ -202,6 +212,16 @@ class BleUtilsModule(private val reactContext: ReactApplicationContext) : callback.invoke(null, map) } + @SuppressLint("MissingPermission") + private fun deviceExposesService( + device: BluetoothDevice, + wantedServiceUuids: Set + ): Boolean { + val uuids = device.uuids + if (uuids.isNullOrEmpty()) return true + return uuids.any { wantedServiceUuids.contains(it.uuid.toString().lowercase()) } + } + private class MyBroadcastReceiver(private val module: BleUtilsModule) : BroadcastReceiver() { @SuppressLint("MissingPermission") override fun onReceive(context: Context, intent: Intent) { diff --git a/android/src/main/java/so/onekey/lib/ble/utils/data/Peripheral.kt b/android/src/main/java/so/onekey/lib/ble/utils/data/Peripheral.kt index 5823740..240ad9e 100644 --- a/android/src/main/java/so/onekey/lib/ble/utils/data/Peripheral.kt +++ b/android/src/main/java/so/onekey/lib/ble/utils/data/Peripheral.kt @@ -26,6 +26,10 @@ class Peripheral( advertising.putBoolean("isConnectable", true) map.putMap("advertising", advertising) + + val serviceUUIDs = Arguments.createArray() + device.uuids?.forEach { serviceUUIDs.pushString(it.uuid.toString()) } + map.putArray("serviceUUIDs", serviceUUIDs) } catch (e: Exception) { // this shouldn't happen Log.e("BleUtils", "Unexpected error on asWritableMap", e) } diff --git a/package.json b/package.json index 378a84e..e037dc9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@onekeyfe/react-native-ble-utils", - "version": "0.1.5", + "version": "0.1.6", "description": "ble uilts", "source": "./src/index.tsx", "main": "./dist/commonjs/index.js", diff --git a/src/index.ts b/src/index.ts index fd379e0..6704659 100644 --- a/src/index.ts +++ b/src/index.ts @@ -57,7 +57,7 @@ class BleUtils { /** * - * @param serviceUUIDs [optional] not used on android, optional on ios. + * @param serviceUUIDs [optional] filter by service UUID (android + ios); empty = no filter. * @returns */ getConnectedPeripherals(serviceUUIDs: string[] = []) { diff --git a/src/type.ts b/src/type.ts index a217511..1f6d920 100644 --- a/src/type.ts +++ b/src/type.ts @@ -33,6 +33,7 @@ export interface Peripheral { name?: string; advertising: AdvertisingData; bondState: BondState; + serviceUUIDs?: string[]; } export interface BondState {