当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");
}