自动检测USB设备连接/断开
问题描述:
我有一个Cocoa应用程序需要通知每当一个设备连接或从USB端口断开连接。我可以使DeviceConnected回调正常工作,但断开USB设备时不会调用DeviceDisconnected功能。自动检测USB设备连接/断开
下面是我的代码:
+ (void)listenForUSBEvents
{
io_iterator_t portIterator = 0;
CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
IONotificationPortRef notifyPort = IONotificationPortCreate(kIOMasterPortDefault);
CFRunLoopSourceRef runLoopSource = IONotificationPortGetRunLoopSource(notifyPort);
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
CFRunLoopAddSource(runLoop, runLoopSource, kCFRunLoopDefaultMode);
CFRetain(matchingDict);
kern_return_t returnCode = IOServiceAddMatchingNotification(notifyPort, kIOMatchedNotification, matchingDict, DeviceConnected, NULL, &portIterator);
if (returnCode == 0)
{
DeviceConnected(nil, portIterator);
}
returnCode = IOServiceAddMatchingNotification(notifyPort, kIOMatchedNotification, matchingDict, DeviceDisconnected, NULL, &portIterator);
if (returnCode == 0)
{
DeviceDisconnected(nil, portIterator);
}
}
@end
void DeviceConnected(void *refCon, io_iterator_t iterator)
{
kern_return_t returnCode = KERN_FAILURE;
io_object_t usbDevice;
while ((usbDevice = IOIteratorNext(iterator)))
{
io_name_t name;
returnCode = IORegistryEntryGetName(usbDevice, name);
if (returnCode != KERN_SUCCESS)
{
return;
}
[[NSNotificationCenter defaultCenter] postNotificationName:deviceConnectedNotification object:nil userInfo:nil];
}
}
void DeviceDisconnected(void *refCon, io_iterator_t iterator)
{
[[NSNotificationCenter defaultCenter] postNotificationName:deviceDiconnectedNotification object:nil userInfo:nil];
}
答
我想通了,我在做什么错。
首先,IOServiceAddMatchingNotification为deviceDisconnected应该是这样的:
returnCode = IOServiceAddMatchingNotification(notifyPort, kIOTerminatedNotification, matchingDict, DeviceDisconnected, NULL, &portIterator);
其次,DeviceDisconnected功能应该是这样的:
void DeviceDisconnected(void *refCon, io_iterator_t iterator)
{
kern_return_t returnCode = KERN_FAILURE;
io_object_t usbDevice;
while ((usbDevice = ioIteratorNext(iterator)))
{
returnCode = IOObjectRelease(usbDevice);
if (returnCode != kIOReturnSuccess)
{
NSLog(@"Couldn't release raw device object: %08x.", returnCode);
}
}
[[NSNotificationCenter defaultCenter] postNotificationName:deviceDiconnectedNotification object:nil userInfo:nil];
}