remoteControlReceivedWithEvent在模拟器中工作,但不在设备中工作

时间:2014-12-14 22:25:25

标签: ios ios8 uiresponder remote-control mpmediaplayercontroller

我正在开发一款可以播放iPod库音乐的应用。我正在通过MPMediaPlayerController播放音乐,方法是从表中检索所选项目并将其传递给详细视图控制器:

MPMediaItem *item = (MPMediaItem *)self.detailItem;
MPMediaItemCollection *collection = [[MPMediaItemCollection alloc] initWithItems:@[item]];
[self.musicPlayer setQueueWithItemCollection:collection];
[self.musicPlayer play];

哪个开始播放音乐。我在Info.plist中设置了以下值以启用后台使用:

UIBackgroundModes
 >Item 0 - audio

这很有效。当我关闭我的应用程序时,音乐一直在播放。所以现在我试图让控制中心的音频控件向我的应用程序发送消息,所以经过一些阅读后我发现我需要做一些事情。所以我创建了一个UIResponder的子类,并添加了以下几行:

- (BOOL)canBecomeFirstResponder {
    return YES;
}
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
    NSLog(@"CustomApp:remoteControlReceivedWithEvent:%@", event.description);
}

我让我的AppDelegate成为自定义UIResponder的子类,我有这个:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    self.window = [[MainWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    self.mainViewController = [[BrowserViewController alloc] initWithNibName:nil bundle:nil];
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.mainViewController];
    self.window.rootViewController = navigationController;
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];

    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self becomeFirstResponder];

    return YES;
}

和这个

- (void)applicationDidEnterBackground:(UIApplication *)application {
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self becomeFirstResponder];
}

现在,我在这里的原因是因为这适用于模拟器而不是设备,我无法弄清楚原因。如果我在模拟器中启动它并打开控制中心并开始按下音频控件,我的自定义UIResponder中的NSLog会显示在调试器中,但在设备上它不会显示。实际发生的是播放/暂停按钮什么都不做,然后如果我按下一个或上一个按钮,它会转到我的iPod应用程序上的下一个或上一个音轨并开始播放。

似乎这个等式中有一些小的遗漏,但我无法弄明白。我尽可能地搜索了文档,但无法找到与此情况相关的任何内容,并且有关此特定功能的文档似乎非常有限。

3 个答案:

答案 0 :(得分:1)

我知道这个答案很老但我在iOS 10中遇到了同样的问题。我的模拟器正确显示了锁屏音频控件,但实际设备没有。对我来说,修复是为了确保在设置AVAudioSession的类别时我 NOT 分配选项:AVAudioSessionCategoryOptionMixWithOthers。

这足以让我的设备无法显示我的锁屏音频控件。所以最后我的解决方案如下:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker|AVAudioSessionCategoryOptionAllowAirPlay|AVAudioSessionCategoryOptionAllowBluetooth|AVAudioSessionCategoryOptionAllowBluetoothA2DP error:&error];

答案 1 :(得分:0)

你的rootViewController中的

- (void)viewDidLoad:(BOOL)animated
{
    [super viewDidAppear:animated];

    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    NSError *setCategoryError = nil;
    BOOL success = [audioSession setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:&setCategoryError];
    if (success) {
        NSError *activationError = nil;
        success = [audioSession setActive:YES error:&activationError];
        if (!success) {
            NSLog(@"%@", activationError);
        }
    }
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self becomeFirstResponder];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];

    [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
    [self resignFirstResponder];
}

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

- (void)remoteControlReceivedWithEvent:(UIEvent *)event
{
    if (event.type == UIEventTypeRemoteControl) {
        NSLog(@"Remote control event %i subtype %i", event.type, event.subtype);

        // example for headphones
        switch (event.subtype) {
            case UIEventSubtypeRemoteControlPlay:
                break;
            case UIEventSubtypeRemoteControlPause:
                break;
            case UIEventSubtypeRemoteControlStop:
                break;
            case UIEventSubtypeRemoteControlTogglePlayPause:
                break;
            case UIEventSubtypeRemoteControlNextTrack:
                break;
            case UIEventSubtypeRemoteControlPreviousTrack:
                break;
            case UIEventSubtypeRemoteControlEndSeekingBackward:
                break;
            case UIEventSubtypeRemoteControlEndSeekingForward:
                break;

            default:
                break;
        }
    }
}

答案 2 :(得分:0)

使用Danilo的回答在viewDidLoad()中试用此代码

-(void)viewDidLoad:(BOOL)animated 
{
    NSError *setCategoryErr = nil;
    NSError *activationErr  = nil;
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:0 error:&setCategoryErr];
    [[AVAudioSession sharedInstance] setActive: YES error: &activationErr];
}