4

当 HID 设备或最后任何 USB/蓝牙设备连接/断开连接时,我如何才能获得简单的回叫?

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

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

谢谢。

4

3 回答 3

8

看看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); }

当串行端口在系统上可用或被删除时,分别调用MySerialPortDeviceWasAddedFunction()和。SerialPortWasRemovedFunction()

相关文档在这里,特别是在标题下Getting Notifications of Device Arrival and Departure

于 2012-03-29T03:06:33.740 回答
3

使用 IOHIDManager 获取通知。

于 2013-10-18T12:18:11.953 回答
2

根据 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");
}
于 2015-10-08T06:51:11.923 回答