4

HIDデバイス、または最後にUSB / Bluetoothデバイスが接続/切断されたときに簡単なコールバックを取得するにはどうすればよいですか?

接続されたジョイスティックと押されたボタン/軸をMac用にきれいに表示するシンプルなアプリを作成しました。私はまだココアに精通していないので、Webビューを使用してUIを作成し、SDLジョイスティックライブラリを使用しました。すべてがうまく機能しています。唯一の問題は、プログラムの実行中にユーザーが何かを接続/切断した場合、ユーザーが新しいジョイスティックを手動でスキャンする必要があることです。

コールバックを使用すると、IIはスキャン関数を呼び出すことができます。デバイスを操作したり、何か凝ったことをしたりしたくはありません。何か新しいことが起こったときを知っているだけです...

ありがとう。

4

3 に答える 3

8

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

MySerialPortDeviceWasAddedFunction()SerialPortWasRemovedFunction()は、シリアルポートがシステムで使用可能になるか、削除されたときにそれぞれ呼び出されます。

関連するドキュメントはここにあり、特に見出しの下にありGetting Notifications of Device Arrival and Departureます。

于 2012-03-29T03:06:33.740 に答える
3

IOHIDManagerを使用して通知を取得します。

于 2013-10-18T12:18:11.953 に答える
2

AndrewとArjunaからの以前の回答に基づいて、Apple HIDデバイスで動作するIOHIDManagerを使用した次のスニペットになりました(たとえば、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");
}
于 2015-10-08T06:51:11.923 に答える