2016-11-02 107 views
0

我有一个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]; 
} 

回答

0

我想通了,我在做什么错。

首先,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]; 
}