Как узнать, когда в Какао подключено устройство HID USB / Bluetooth? - PullRequest
3 голосов
/ 29 марта 2012

Как получить простой обратный вызов, когда устройство HID или, наконец, любое устройство USB / Bluetooth подключено / отключено?

Я сделал простое приложение, которое показывает подключенные джойстики и нажатые кнопки / ось для Mac. Поскольку я еще не очень знаком с какао, я создал пользовательский интерфейс с помощью веб-просмотра и использовал библиотеку SDL Joystick. Все работает хорошо, единственная проблема в том, что пользователю нужно вручную искать новые джойстики, если он / она что-то подключает / отключает во время работы программы.

При обратном вызове я могу просто вызвать функцию сканирования. Я не хочу обращаться с устройством или делать что-то необычное, просто знаю, когда происходит что-то новое ...

Спасибо.

Ответы [ 3 ]

7 голосов
/ 29 марта 2012

Посмотрите на IOServiceAddMatchingNotification() и связанные с ним функции.Я работал с ним только в контексте последовательных портов (которые фактически являются адаптерами USB-последовательный порт, хотя это не имеет значения), но это должно быть применимо к любому доступному IOKit-устройству.Я не уверен насчет Bluetooth, но он должен по крайней мере работать на устройствах 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() вызываются, когда последовательный порт становится доступным в системе или удаляется, соответственно. здесь , особенно под заголовком Getting Notifications of Device Arrival and Departure.

3 голосов
/ 18 октября 2013

Используйте IOHIDManager для получения уведомлений.

1 голос
/ 08 октября 2015

Основываясь на предыдущих ответах Эндрю и Арджуны, я получил следующий фрагмент с помощью IOHIDManager, который должен работать с устройством Apple HID (например, был протестирован трекпад bluetooth). Похоже, это также отправляет уведомления более одного раза без необходимости очищать / уменьшать что-либо.

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