Подтвердить что ты не робот

IOS 4: пульты дистанционного управления для фонового звука

В настоящее время я пытаюсь настроить фоновый звук для приложения, которое я разрабатываю для iOS 4. У приложения нет специального музыкального проигрывателя viewController, однако, в отличие от других фоновых аудио-приложений, таких как Pandora, которые делает задачу несколько более запутанной.

Я правильно установил соответствующие настройки Info.plist и у меня есть объект AVAudioPlayer в моем делете приложения, доступный извне. Когда пользователь воспроизводит песню, я заменяю AVAudioPlayer на новую, инициализированную песней, и воспроизвожу ее. Все это отлично работает, но теперь я не знаю, как поддерживать поддержку событий дистанционного управления.

Основываясь на документации Apple, у меня есть следующее:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self becomeFirstResponder];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
    [self resignFirstResponder];
}

- (BOOL)canBecomeFirstResponder {
    return YES;
}

- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
    switch(event.subtype) {
        case UIEventSubtypeRemoteControlTogglePlayPause:
            if([iPhoneAppDelegate backgroundAudioPlayer].playing)
                [iPhoneAppDelegate pauseBackgroundAudioPlayer];
            else
                [iPhoneAppDelegate playBackgroundAudioPlayer];
            break;
    }
}

Дело в том, где я могу это поставить? Документация Apple, похоже, предполагает, что это должно идти в каком-то контроллере вида где-то, но в моем приложении много контроллеров и контроллеров навигации. Где бы я ни пыталась это поделать, почему-то нажатие кнопки Toggle Play/Pause на пульте дистанционного управления многозадачного лотка приводит к тому, что песня просто приостанавливается на мгновение, а затем приостанавливается или каким-то образом заставляет песню проигрывать дважды.

4b9b3361

Ответ 1

Я нашел несколько решений для получения глобальных событий удаленного управления на форумах разработчиков Apple после небольшого поиска.

Один из способов заключается в подклассе UIWindow и переопределении его remoteControlReceivedWithEvent:.

Второй, возможно, более приятным способом является подкласс UIApplication и переопределить sendEvent:. Таким образом, вы можете перехватывать все события удаленного управления и обрабатывать их там по всему миру, а другие респондеры не будут обрабатывать их позже в цепочке ответчиков.

- (void)sendEvent:(UIEvent *)event {
     if (event.type == UIEventTypeRemoteControl) {
          // Handle event
     }
     else
          [super sendEvent:event];
}

Ответ 2

Примеры документации немного вводят в заблуждение, но нет необходимости подклассифицировать что-либо в любом месте. Правильное место для размещения remoteControlReceivedWithEvent: находится в делетете приложения, так как оно остается в цепочке ответчиков независимо от того, находится ли приложение на переднем плане или нет. Кроме того, события начала и окончания приема и дистанционного управления должны основываться на том, действительно ли вам нужны события, а не на видимости какого-либо случайного вида.

Ответ 3

Второй метод не работал у меня, sendEvent никогда не вызывался. Однако первый метод работал просто красиво (подклассификация UIWindow).

Ответ 4

Я боролся с этим на какое-то время, и ни один из ответов выше не работал. Ошибка в моем коде, и я надеюсь, что это поможет кому-то прочитать это, было то, что у меня был набор AudioSession для смешивания с другими. Вы хотите быть аудиопроигрывателем переднего плана для получения событий дистанционного управления. Проверьте, есть ли код INCORRECT следующим образом:

    [[AVAudioSession sharedInstance] setDelegate: self];
    [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: nil];
    UInt32 doSetProperty = 0;
    AudioSessionSetProperty (
                             kAudioSessionProperty_OverrideCategoryMixWithOthers,
                             sizeof (doSetProperty),
                             &doSetProperty
                             );
    NSError *activationError = nil;
    [[AVAudioSession sharedInstance] setActive: YES error: &activationError];       

И удалите AudioSessionSetProperty или измените doSetProperty на 1.

Ответ 7

Одна вещь, которая, кажется, влияет на это поведение, - это любые параметры категории, которые вы задали для своего AVAudioSession, используя setCategory: withOptions: error: вместо просто setCategory: error:. В частности, из проб и ошибок, похоже, что если вы установите AVAudioSessionCategoryOptionMixWithOthers, вы не будете получать события дистанционного управления; теперь играющие элементы управления будут управлять iPod. Если вы установите AVAudioSessionCategoryOptionDuckOthers, вы получите события дистанционного управления, но похоже, что может быть какая-то неопределенность в отношении того, какое приложение контролируется. Установка categoryOptions в 0 или просто вызов setCategory: ошибка: работает лучше всего.