我正在开发一款可以播放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应用程序上的下一个或上一个音轨并开始播放。
似乎这个等式中有一些小的遗漏,但我无法弄明白。我尽可能地搜索了文档,但无法找到与此情况相关的任何内容,并且有关此特定功能的文档似乎非常有限。
答案 0 :(得分:1)
我知道这个答案很老但我在iOS 10中遇到了同样的问题。我的模拟器正确显示了锁屏音频控件,但实际设备没有。对我来说,修复是为了确保在设置AVAudioSession的类别时我 NOT 分配选项:AVAudioSessionCategoryOptionMixWithOthers。
这足以让我的设备无法显示我的锁屏音频控件。所以最后我的解决方案如下:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker|AVAudioSessionCategoryOptionAllowAirPlay|AVAudioSessionCategoryOptionAllowBluetooth|AVAudioSessionCategoryOptionAllowBluetoothA2DP error:&error];
答案 1 :(得分:0)
:
- (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];
}