iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了。如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,AvPlayer播放的话,要实现完美的后台音频播放,依据app的功能需要,可能需要实现几个关键的功能。
首先,播放音频之前先要设置AVAudioSession模式,通常只用来播放的App可以设为AVAudioSessionCategoryPl
- AVAudioSession
*session = [AVAudioSession sharedInstance]; - [session
setCategory:AVAudioSessionCategoryPl ayback error:nil]; - [session
setActive:YES error:nil];
1。通知OS该app支持background audio。缺省情况下,当按下home键时,当前正在运行的程序被suspend,状态从active变成in-active,也就是说如果正在播放音频,按下HOME后就会停止。这里需要让app在按在HOME后,转到后台运行而非被suspend,解决办法是在程序的-info.plist中增加required background modes这个key项,并选择App plays audio这个value项。
2。现在按下HOME键后,程序退到后台,但是声音仍在播放。但是如果要实现播放列表的依次播放、循环播放,即放完一首后自动切换到下一首,问题来了,当App在后台放完一首后,就会停下来。原因是在后台运行时,一旦声音停下来,程序也随之suspend,因此在切换文件加载的间隙,程序就会被suspend。曾经有山寨的解决办法是专门起一个player的实例连续不停的放同一无声音片断,阻止程序被suspend。这里提供的方法是通过申请后台taskID达到后台切换播放文件的功能。
即声明后台task id,并通过beginBackgroundTaskWithE
首先,要在viewdidload中
[UIApplication
否则,无法切换到下一首,接下来
- UIBackgroundTaskIdentifi
er newTaskId = UIBackgroundTaskInvalid; -
- [avPlayer
play]; - newTaskId
= [[UIApplication sharedApplication] beginBackgroundTaskWithE xpirationHandler:NULL]; - if
(newTaskId != UIBackgroundTaskInvalid && oldTaskId != UIBackgroundTaskInvalid) { -
[[UIApplication sharedApplication] endBackgroundTask: oldTaskId];} - oldTaskId
= newTaskId;
当然,还有更方便的办法就是在resignActive时beginBackgroundTaskWithE
3。我们知道,ipod播放程序在后台时,双击HOME键,会有个控制界面,可以对它进行播放控制。
如果您想让您的app可以像ipod一样在后台也可以方便的通过双击HOME键来控制,就要用到远程控制事件了。
首先在viewdidload等初始化的地方声明App接收远程控制事件,并在相应地方结束声明
- -
(void) viewWillAppear:(BOOL)animated - {
- [super
viewWillAppear:animated]; - [UIApplication
sharedApplication] beginReceivingRemoteCont rolEvents]; - [self
becomeFirstResponder]; - }
-
- -
(void) viewWillDisappear:(BOOL)animated - {
- [super
viewWillDisappear:animated]; - [UIApplication
sharedApplication] endReceivingRemoteContro lEvents]; - [self
resignFirstResponder]; - }
定义
- -
(BOOL)canBecomeFirstResponder - {
-
return YES; - }
最后定义
- -
(void) remoteControlReceivedWit hEvent: (UIEvent *) receivedEvent { -
if (receivedEvent.type == UIEventTypeRemoteControl ) { -
-
switch (receivedEvent.subtype) { -
-
case UIEventSubtypeRemoteCont rolTogglePlayPause: -
[self playButtonPressed:playButton]; -
[self testing]; -
break; -
-
case UIEventSubtypeRemoteCont rolPreviousTrack: -
[self rewButtonReleased:(UIButton *)rewButton]; -
break; -
-
case UIEventSubtypeRemoteCont rolNextTrack: -
[self ffwButtonReleased:(UIButton *)ffwButton]; -
break; -
-
default: -
break; -
} -
} - }
4. 至此,您有播放App已经相当完美了,还有最后一个问题,那就是当用户使用耳机时,问题又来了。系统默认当插入耳机时,正在播放的声音不中断,直接切换到耳机播放,而当拔出耳机时,播放停止。如果这种行为满足您的要求,那OK,否则您就需要进一步研究耳机检测和声音路由切换的问题。