2013-03-13 56 views
17

这个问题是关于这个问题的代码:Detect headphone button presses in OS X检测硬件耳机机在Mac

他们的答案被标记为正确,但我不能让他们的代码工作(这可能是因为我的知识缺乏的目标c)。我遵循他们的指示,并修改了三个文件。这是我曾尝试(我也看着苹果由于IOKit文件,但没有找到任何耳机硬件按钮文档):

AwesomeClass.h

#import <Cocoa/Cocoa.h> 
#include "KeyboardPaneController.h" 

@interface AwesomeClass : KeyboardPaneController 
+ (NSArray *) allKeyboards; 
- (void) initKeyboardElements: (NSArray *) elements; 
- (void) ddhidQueueHasEvents: (DDHidQueue *) hidQueue; 
@end 

AwesomeClass.m

#import "AwesomeClass.h" 
#import "DDHidLib.h" 

@implementation AwesomeClass 

+ (NSArray *) allKeyboards; 
{ 
    NSArray *array = [DDHidDevice allDevicesMatchingUsagePage: kHIDPage_Consumer 
                 usageId: kHIDUsage_GD_Pointer 
                withClass: self 
              skipZeroLocations: NO]; 

    //Only return "Apple Mikey HID Driver", if not found, return nil. 
    for (DDHidDevice *device in array) { 
     if ([[device productName] isEqualToString:@"Apple Mikey HID Driver"]) { 
      return [NSArray arrayWithObject:device]; 
     } 
    } 
    return nil; 
} 

- (void) initKeyboardElements: (NSArray *) elements; 
{ 
    NSEnumerator * e = [elements objectEnumerator]; 
    DDHidElement * element; 
    while (element = [e nextObject]) 
    { 
     unsigned usagePage = [[element usage] usagePage]; 
     unsigned usageId = [[element usage] usageId]; 
     if (usagePage == kHIDPage_GenericDesktop) 
     { 
      if ((usageId >= 0x89) && (usageId <= 0x8D)) 
      { 
       [mKeyElements addObject: element]; 
      } 
     } 
     NSArray * subElements = [element elements]; 
     if (subElements != nil) 
      [self initKeyboardElements: subElements]; 
    } 
} 

- (void) ddhidQueueHasEvents: (DDHidQueue *) hidQueue; 
{ 
    DDHidEvent * event; 
    while ((event = [hidQueue nextEvent])) 
    { 
     DDHidElement * element = [self elementForCookie: [event elementCookie]]; 
     unsigned usageId = [[element usage] usageId]; 
     SInt32 value = [event value]; 
     if (value == 1) 
      [self ddhidKeyboard: self keyDown: usageId]; 
    } 
} 
@end 

...以及在KeyboardPaneController.m中修改一行(在说明中显示)。由于缺乏框架文档,很难找到答案(海报已经脱机一年多了,所以我假设我可能不会得到回应)。代码在狮子身上进行了测试,我有山狮,所以这可能是问题。

我知道这是绝对有可能实现的,因为iTunes对我的耳机按键(这有点微妙)非常敏感。我希望能够使用耳机上的按钮而不是iTunes来控制Spotify。

+0

'+ allKeyboards'返回'nil'还是找到了某些内容?名称,看看是否有一个看起来很有前途的名字,但与该代码预期的名称不同?(通常,您需要更清楚地了解该代码的失败原因)。 – 2013-03-16 21:52:45

+0

我知道所有键盘都没有返回耳机或声卡,但我会看到正是allKeyboards返回并发布结果。 – alexy13 2013-03-16 22:53:02

回答

8

测试表明它没有实现为键盘了:

id array = [[DDHidDevice allDevices] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"productName == \"Apple Mikey HID Driver\""]]; 
    DDHidDevice *mic = [array count] ? [array objectAtIndex:0] : nil; 
    // it isn't a keyboard 
    NSLog(@"%@", mic.primaryUsage); 
    assert(mic.usage==1 && mic.usagePage==12); 

你不能把它当作HIDKeyboard或者(试过,不发送按键),也不是HIDMouse或HID操纵杆。

我挖掘了HIDQueue类并检查了mikey是否触发了任何低级事件并且它触发了低级事件! queueCallbackFunction被称为按下按钮(如果您不过滤队列中的特定事件,要过滤它,请参阅DDHidKeyboard中的initWithKeyboardEvents

现在,您只需将低级别事件映射到正确的按钮,或者将它全部包装在一个不错的班级中,下面是GitHub上的班级和相关代码示例:

+0

它不是特定于一个耳机,但现在有APPLE_MIC_ONLY 1定义。为什么?因为IOKit真的不区分苹果遥控器或麦克风,甚至是触控板 – 2013-03-17 13:31:11

+0

人们可以改进这种检测算法,但我只有苹果麦克风测试 - 无论如何它都在方法'allMikeys' – 2013-03-17 13:32:15