【问题标题】:remoteControlReceivedWithEvent works in simulator but not deviceremoteControlReceivedWithEvent 适用于模拟器,但不适用于设备
【发布时间】:2015-02-13 00:09:03
【问题描述】:

我正在开发一个应用程序,它将播放 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 应用程序上的下一个或上一个曲目并开始播放。

这个等式似乎缺少一些小东西,但我无法弄清楚。我已尽我所能搜索文档,但找不到与这种情况相关的任何内容,而且有关此特定功能的文档似乎非常有限。

【问题讨论】:

    标签: ios ios8 uiresponder remote-control mpmediaplayercontroller


    【解决方案1】:

    viewDidLoad() 中试试这个代码,并附上 Danilo 的答案

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        【解决方案3】:

        在你的 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;
                }
            }
        }
        

        【讨论】:

        • 感谢您的回复。我从其他地方删除了我为此拥有的所有代码,并像你说的那样把它放在我的 rootViewController 中。再一次,我可以通过拉起控制中心并按下播放/暂停下一个/上一个来让它在模拟器中工作,我可以看到 NSLog 打印出来但是当我在设备上启动它时它对我的应用程序没有任何作用尝试控制上一个正在播放音乐的应用程序。还有什么我可能会错过的吗?
        • in viewDidLoad 尝试在 [super viewDidLoad] 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) { [self trackLog:@"RadioIO no AudioSession available!" error:activationError]; } } 之后立即添加此代码
        • 在 viewDidLoad NSError *setCategoryErr = nil 中试试这个NSError *activationErr = nil; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:0 error:&setCategoryErr]; [[AVAudioSession sharedInstance] setActive: YES error: &activationErr];
        猜你喜欢
        • 2012-11-01
        • 2011-03-08
        • 2011-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多