From 9fec2a29a14b09f9c9e6655a082a57c4f79c55ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B1=9F=E5=8F=8B=E8=89=AF?= Date: Wed, 12 Mar 2025 15:00:20 +0800 Subject: [PATCH] mididevice Added serviceUUIDs attribute in broadcast. (Can filter Bluetooth devices during search phase) --- .../BluetoothDeviceExtension.kt | 11 +++++ .../fluttermidicommand/Device.kt | 1 + .../FlutterMidiCommandPlugin.kt | 16 +++++-- example/lib/main.dart | 2 +- .../SwiftFlutterMidiCommandPlugin.swift | 44 ++++++++++++++----- 5 files changed, 59 insertions(+), 15 deletions(-) create mode 100644 android/src/main/kotlin/com/invisiblewrench/fluttermidicommand/BluetoothDeviceExtension.kt diff --git a/android/src/main/kotlin/com/invisiblewrench/fluttermidicommand/BluetoothDeviceExtension.kt b/android/src/main/kotlin/com/invisiblewrench/fluttermidicommand/BluetoothDeviceExtension.kt new file mode 100644 index 00000000..d1def683 --- /dev/null +++ b/android/src/main/kotlin/com/invisiblewrench/fluttermidicommand/BluetoothDeviceExtension.kt @@ -0,0 +1,11 @@ +package com.invisiblewrench.fluttermidicommand + +import android.bluetooth.BluetoothDevice + +private val deviceServiceUUIDs = mutableMapOf>() + +var BluetoothDevice.serviceUUIDs: List + get() = deviceServiceUUIDs[address] ?: listOf() + set(value) { + deviceServiceUUIDs[address] = value + } \ No newline at end of file diff --git a/android/src/main/kotlin/com/invisiblewrench/fluttermidicommand/Device.kt b/android/src/main/kotlin/com/invisiblewrench/fluttermidicommand/Device.kt index 368e31b5..318eff76 100644 --- a/android/src/main/kotlin/com/invisiblewrench/fluttermidicommand/Device.kt +++ b/android/src/main/kotlin/com/invisiblewrench/fluttermidicommand/Device.kt @@ -12,6 +12,7 @@ abstract class Device { lateinit var midiDevice: MidiDevice protected var receiver:MidiReceiver? = null protected var setupStreamHandler: FMCStreamHandler? = null + var serviceUUIDs: List = listOf() constructor(id: String, type: String) { this.id = id diff --git a/android/src/main/kotlin/com/invisiblewrench/fluttermidicommand/FlutterMidiCommandPlugin.kt b/android/src/main/kotlin/com/invisiblewrench/fluttermidicommand/FlutterMidiCommandPlugin.kt index 989d4764..d8ea8b3e 100644 --- a/android/src/main/kotlin/com/invisiblewrench/fluttermidicommand/FlutterMidiCommandPlugin.kt +++ b/android/src/main/kotlin/com/invisiblewrench/fluttermidicommand/FlutterMidiCommandPlugin.kt @@ -439,6 +439,9 @@ class FlutterMidiCommandPlugin : FlutterPlugin, ActivityAware, MethodCallHandler Log.d("FlutterMIDICommand", "onScanResult: ${result?.device?.address} - ${result?.device?.name}") result?.also { if (!discoveredDevices.contains(it.device)) { + // Get and save serviceUUIDs + val serviceUUIDs = result.scanRecord?.serviceUuids?.map { it.uuid.toString() } ?: listOf() + it.device.serviceUUIDs = serviceUUIDs discoveredDevices.add(it.device) setupStreamHandler.send("deviceAppeared") } @@ -551,11 +554,9 @@ class FlutterMidiCommandPlugin : FlutterPlugin, ActivityAware, MethodCallHandler var id = it.address; Log.d("FlutterMIDICommand", "add discovered device $ type ${it.type}") - if (list.contains(id)) { - Log.d("FlutterMIDICommand", "device already in list $id") - } else { + if (!list.contains(id)) { Log.d("FlutterMIDICommand", "add native device $id type ${it.type}") - list[id] = mapOf( + val deviceMap = mutableMapOf( "name" to it.name, "id" to id, "type" to "BLE", @@ -563,6 +564,13 @@ class FlutterMidiCommandPlugin : FlutterPlugin, ActivityAware, MethodCallHandler "inputs" to listOf(mapOf("id" to 0, "connected" to false)), "outputs" to listOf(mapOf("id" to 0, "connected" to false)) ) + + // Only add to device information if serviceUUIDs is not empty + if (it.serviceUUIDs.isNotEmpty()) { + deviceMap["serviceUUIDs"] = it.serviceUUIDs + } + + list[id] = deviceMap } } diff --git a/example/lib/main.dart b/example/lib/main.dart index 5260b2fb..53edd29e 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -242,7 +242,7 @@ class MyAppState extends State { style: Theme.of(context).textTheme.headlineSmall, ), subtitle: Text( - "ins:${device.inputPorts.length} outs:${device.outputPorts.length}, ${device.id}, ${device.type}"), + "ins:${device.inputPorts.length} outs:${device.outputPorts.length}, ${device.id}, ${device.type}, serviceUUID:${device.serviceUUIDs.first.str}"), leading: Icon(device.connected ? Icons.radio_button_on : Icons.radio_button_off), diff --git a/ios/Classes/SwiftFlutterMidiCommandPlugin.swift b/ios/Classes/SwiftFlutterMidiCommandPlugin.swift index 33e55797..56863024 100644 --- a/ios/Classes/SwiftFlutterMidiCommandPlugin.swift +++ b/ios/Classes/SwiftFlutterMidiCommandPlugin.swift @@ -69,6 +69,10 @@ public class SwiftFlutterMidiCommandPlugin: NSObject, CBCentralManagerDelegate, let midiLog = OSLog(subsystem: "com.invisiblewrench.FlutterMidiCommand", category: "MIDI") + + // Add a dictionary to store serviceUUIDs + private var peripheralServiceUUIDs: [CBPeripheral: [String]] = [:] + public static func register(with registrar: FlutterPluginRegistrar) { #if os(macOS) let channel = FlutterMethodChannel(name: "plugins.invisiblewrench.com/flutter_midi_command", binaryMessenger: registrar.messenger) @@ -560,17 +564,28 @@ public class SwiftFlutterMidiCommandPlugin: NSObject, CBCentralManagerDelegate, for periph:CBPeripheral in discoveredDevices { let id = periph.identifier.uuidString - devices.append([ - "name" : periph.name ?? "Unknown", - "id" : id, - "type" : "BLE", - "connected":(connectedDevices.keys.contains(id) ? "true" : "false"), - "inputs" : [["id":0, "connected":false] as [String:Any]], - "outputs" : [["id":0, "connected":false] as [String:Any]] - ]) + let serviceUUID = periph.discoverServices(nil) + + // 获取存储的serviceUUIDs + let serviceUUIDs = peripheralServiceUUIDs[periph] ?? [] + + var deviceInfo: [String: Any] = [ + "name": periph.name ?? "Unknown", + "id": id, + "type": "BLE", + "connected": (connectedDevices.keys.contains(id) ? "true" : "false"), + "inputs": [["id":0, "connected":false] as [String:Any]], + "outputs": [["id":0, "connected":false] as [String:Any]] + ] + + // 只有当serviceUUIDs不为空时才添加到设备信息中 + if !serviceUUIDs.isEmpty { + deviceInfo["serviceUUIDs"] = serviceUUIDs + } + + devices.append(deviceInfo) } - - + // ########### // CONNECTED BLE DEVICES (which are no longer discoverable) // ########### @@ -898,6 +913,15 @@ public class SwiftFlutterMidiCommandPlugin: NSObject, CBCentralManagerDelegate, print("central didDiscover \(peripheral)") if !discoveredDevices.contains(peripheral) { discoveredDevices.insert(peripheral) + + // Get serviceUUIDs from advertisementData + var serviceUUIDs: [String] = [] + if let services = advertisementData[CBAdvertisementDataServiceUUIDsKey] as? [CBUUID] { + serviceUUIDs = services.map { $0.uuidString } + } + + // Store serviceUUIDs in the peripheral's associated data + peripheralServiceUUIDs[peripheral] = serviceUUIDs updateSetupState(data: "deviceAppeared") } }