iOS 4: пульты дистанционного управления для фонового звука - PullRequest
31 голосов
/ 11 августа 2010

В настоящее время я пытаюсь настроить фоновый звук для приложения, которое я разрабатываю для 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 на пульте дистанционного управления лотка для многозадачности либо приводит к тому, что песня на мгновение приостанавливается, а затем прерывается, либо как-то заставляет песню проигрываться дважды.

Ответы [ 7 ]

37 голосов
/ 15 января 2012

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

19 голосов
/ 11 августа 2010

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

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

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

- (void)sendEvent:(UIEvent *)event {
     if (event.type == UIEventTypeRemoteControl) {
          // Handle event
     }
     else
          [super sendEvent:event];
}
4 голосов
/ 19 декабря 2010

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

3 голосов
/ 30 мая 2012

Я боролся с этим некоторое время, и ни один из ответов выше не работал.Ошибка в моем коде, и я надеюсь, что это поможет кому-то прочесть это, заключалась в том, что я настроил AudioSession для смешивания с другими.Вы хотите быть на переднем плане аудиоплеером, чтобы получать события дистанционного управления.Проверьте, есть ли у вас НЕПРАВИЛЬНЫЙ код:

    [[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.

0 голосов
/ 22 сентября 2014

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

0 голосов
/ 05 сентября 2013
0 голосов
/ 27 июля 2011

Нет необходимости создавать подкласс Window или пересылать события.Просто сделайте это с вашего основного контроллера.Подробнее см. Пример Audio Mixer (MixerHost).

http://developer.apple.com/LIBRARY/IOS/#samplecode/MixerHost/Listings/Classes_MixerHostViewController_m.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...