2013-03-13 98 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