16

这个问题是关于这个问题的代码:Detect headphone button presses in OS X

他们的答案被标记为正确,但是我无法让他们的代码正常工作(这可能是因为我对 Objective-c 缺乏了解)。我按照他们的指示,修改了三个文件。这是我尝试过的(我还查看了 Apple 的 IOKit 文档,但找不到任何耳机硬件按钮文档):

真棒类.h

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

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

真棒类.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。

4

1 回答 1

9

测试表明它不再作为键盘实现:

    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 上的类示例和相关代码。

于 2013-03-17T11:21:12.027 回答