如何在HID设备或最后任何USB / Bluetooth设备连接/断开连接时进行简单回叫?
我制作了一个简单的应用程序,以漂亮的方式显示连接的操纵杆和按下的按钮/轴。由于我对cocoa不是很熟悉,我使用webview制作了UI,并使用了SDL Joystick库。 一切都运行良好,唯一的问题是如果用户在程序运行时连接/断开某些东西,用户需要手动扫描新的操纵杆。 p>
通过回调,我可以调用扫描功能。我不想处理设备或做一些奇特的事情,只知道什么时候发生了新的事情......
感谢。
答案 0 :(得分:7)
查看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);
while (IOIteratorNext(portIterator)) {}; // Run out the iterator or notifications won't start (you can also use it to iterate the available devices).
// Also register for removal notifications
IONotificationPortRef terminationNotificationPort = IONotificationPortCreate(kIOMasterPortDefault);
CFRunLoopAddSource(CFRunLoopGetCurrent(),
IONotificationPortGetRunLoopSource(terminationNotificationPort),
kCFRunLoopDefaultMode);
result = IOServiceAddMatchingNotification(terminationNotificationPort,
kIOTerminatedNotification,
matchingDict,
SerialPortWasRemovedFunction,
self, // refCon/contextInfo
&portIterator);
while (IOIteratorNext(portIterator)) {}; // Run out the iterator or notifications won't start (you can also use it to iterate the available devices).
当串行端口在系统上可用或被删除时,将调用我的SerialPortDeviceWasAddedFunction()
和SerialPortWasRemovedFunction()
。
相关文档is here,尤其是标题Getting Notifications of Device Arrival and Departure
。
答案 1 :(得分:3)
使用IOHIDManager获取通知。
答案 2 :(得分:1)
基于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");
}