4

Я работаю над приложением, которое будет воспроизводить музыку из библиотеки iPod. Я играю музыку через MPMediaPlayerController путем извлечения выбранного элемента из таблицы и передачи его в контроллер представления деталь:remoteControlReceivedWithEvent работает в симуляторе, но не в устройстве

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]; 
} 

Теперь, моя причина, почему я здесь, потому что это работает в симуляторе, но не в устройстве, и я не могу понять, почему. Если я запустил это в симуляторе и подниму центр управления и начну нажимать элементы управления аудио, то NSLog в моем пользовательском UIResponder отобразится в отладчике, но на устройстве это не так. Что на самом деле происходит, так это то, что кнопка воспроизведения/паузы ничего не делает, затем, если я нажимаю следующую или предыдущую кнопку, она переходит к следующей или предыдущей дорожке в моем приложении iPod и начинает ее воспроизводить.

Кажется, что есть что-то маленькое, отсутствующее в этом уравнении, но я не могу понять это. Я искал документацию как можно лучше, но не могу найти ничего, связанного с этой ситуацией, и документация по этой конкретной функции кажется довольно ограниченной.

ответ

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; 
     } 
    } 
} 
+0

Спасибо, что ответили. Я удалил весь код, который у меня был для этого, из других мест и поместил его в свой rootViewController, как вы сказали. Еще раз, хотя, я могу заставить это работать в симуляторе, потянув центр управления и нажав play/pause next/previous, и я могу увидеть распечатку NSLog, но когда я запускаю его на устройстве, он ничего не делает с моим приложением и пытается контролировать последнее приложение, которое воспроизводит музыку. Есть ли что-то еще, что я мог бы потерять? –

+0

in viewDidLoad попробуйте добавить этот код сразу после [super viewDidLoad] 'AVAudioSession * audioSession = [AVAudioSession sharedInstance]; \t NSError * setCategoryError = nil; BOOL success = [audioSession setCategory: AVAudioSessionCategoryPlayback withOptions: AVAudioSessionCategoryOptionDefaultToSpeaker error: & setCategoryError]; if (success) { \t NSError * activationError = nil; success = [audioSession setActive: YES error: & activationError]; если (! Успех) { \t [self trackLog: @ "RadioIO no AudioSession доступно!" Ошибка: activationError]; } \t} ' – Danilo

+0

Попробуйте в viewDidLoad NSError * setCategoryErr = ноль; NSError * activationErr = nil; [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback withOptions: 0 error: & setCategoryErr]; [[AVAudioSession sharedInstance] setActive: YES error: & activErr]; –

0

Попробуйте этот код в 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]; 

} 
1

Я знаю, что этот ответ старый, но я страдал от того же выпуска в ИО 10. Мой симулятор правильно отображал управление звуком блокировки экрана, но на самом деле этого устройства не было. Для меня было исправлено, что при настройке категории AVAudioSession я был NOT, назначив опцию: AVAudioSessionCategoryOptionMixWith Other.

Этого было достаточно для того, чтобы мое устройство не отображало элементы управления звуком блокировки экрана. Таким образом, в конечном итоге мой раствор выглядит следующим образом:

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