如何知道HID USB/蓝牙设备何时在Cocoa中连接



当HID设备或最终任何USB/蓝牙设备连接/断开时,我如何获得简单的回拨

我做了一个简单的应用程序,以一种漂亮的方式显示连接的操纵杆和按下的按钮/轴。由于我还不太熟悉cocoa,所以我使用webview制作了UI,并使用了SDL摇杆库。一切都很好,唯一的问题是,如果用户在程序运行时连接/断开某些东西,他/她需要手动扫描新的操纵杆。

通过回调,我可以直接调用Scan函数。我不想处理这个设备或做一些花哨的事情,只要知道什么时候有新的事情发生。。。

谢谢。

查看IOServiceAddMatchingNotification()和相关函数。我只在串行端口的上下文中使用过它(实际上是USB到串行适配器,尽管这无关紧要),但它应该适用于任何IOKit可访问的设备。我不确定蓝牙,但它至少应该适用于USB设备。以下是我使用的代码片段:

IONotificationPortRef notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
CFRunLoopAddSource(CFRunLoopGetCurrent(), 
               IONotificationPortGetRunLoopSource(notificationPort), 
               kCFRunLoopDefaultMode);
CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOSerialBSDServiceValue);
CFRetain(matchingDict); // Need to use it twice and IOServiceAddMatchingNotification() consumes a reference
CFDictionaryAddValue(matchingDict, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDRS232Type));
io_iterator_t portIterator = 0;
// Register for notifications when a serial port is added to the system
kern_return_t result = IOServiceAddMatchingNotification(notificationPort,
                                                        kIOPublishNotification,
                                                        matchingDictort,
                                                        SerialDeviceWasAddedFunction,
                                                        self,           
                                                        &portIterator);
io_object_t d;
// Run out the iterator or notifications won't start (you can also use it to iterate the available devices).
while ((d = IOIteratorNext(iterator))) { IOObjectRelease(d); }
// Also register for removal notifications
IONotificationPortRef terminationNotificationPort = IONotificationPortCreate(kIOMasterPortDefault);
CFRunLoopAddSource(CFRunLoopGetCurrent(),
                   IONotificationPortGetRunLoopSource(terminationNotificationPort),
                   kCFRunLoopDefaultMode);
result = IOServiceAddMatchingNotification(terminationNotificationPort,
                                          kIOTerminatedNotification,
                                          matchingDict,
                                          SerialPortWasRemovedFunction,
                                          self,         // refCon/contextInfo
                                          &portIterator);
io_object_t d;
// Run out the iterator or notifications won't start (you can also use it to iterate the available devices).
while ((d = IOIteratorNext(iterator))) { IOObjectRelease(d); }

当系统上的串行端口可用或被删除时,会分别调用我的SerialPortDeviceWasAddedFunction()SerialPortWasRemovedFunction()

这里有相关文件,特别是标题为Getting Notifications of Device Arrival and Departure的文件。

使用IOHIDManager获取通知。

根据Andrew和Arjuna早些时候的回答,我使用IOHIDManager得出了以下片段,该片段应该可以与Apple HID设备配合使用(例如,测试了蓝牙触控板)。这似乎还可以多次发送通知,而无需清除/减少任何内容。

- (void) startHIDNotification
{
ioHIDManager = IOHIDManagerCreate ( kCFAllocatorDefault, kIOHIDManagerOptionNone  );
CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOHIDDeviceKey);
CFDictionaryAddValue(matchingDict, CFSTR(kIOHIDManufacturerKey), CFSTR("Apple"));
IOHIDManagerSetDeviceMatching (ioHIDManager, matchingDict);
IOHIDManagerRegisterDeviceMatchingCallback( ioHIDManager, AppleHIDDeviceWasAddedFunction, (__bridge void *)(self) );
IOHIDManagerRegisterDeviceRemovalCallback( ioHIDManager, AppleHIDDeviceWasRemovedFunction, (__bridge void *)(self) );
hidNotificationRunLoop = CFRunLoopGetCurrent();
IOHIDManagerScheduleWithRunLoop(ioHIDManager,
                                hidNotificationRunLoop,
                                kCFRunLoopDefaultMode);
}

以及的回调方法

void AppleHIDDeviceWasAddedFunction( void *                  context,
                             IOReturn                result,
                             void *                  sender,
                             IOHIDDeviceRef          device)
{
     NSLog(@"added");
}
void AppleHIDDeviceWasRemovedFunction( void *                  context,
                             IOReturn                result,
                             void *                  sender,
                             IOHIDDeviceRef          device)
{
     NSLog(@"removed");
}

最新更新