扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
现在后台只有两种方式一直运行。其他都不可行
成都创新互联专业为企业提供涿鹿网站建设、涿鹿做网站、涿鹿网站设计、涿鹿网站制作等企业网站建设、网页设计与制作、涿鹿企业网站模板建站服务,10年涿鹿做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
1、音乐允许后台一直运行。
2、定位允许后台一直运行。
由于苹果的这种特性,建议在前台时扫描蓝牙设备时,设置CBCentralManagerScanOptionAllowDuplicatesKey为NO;在后台扫描蓝牙时,设置CBCentralManagerScanOptionAllowDuplicatesKey为YES
iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了。如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,AvPlayer播放的话,要实现完美的后台音频播放,依据app的功能需要,可能需要实现几个关键的功能。
首先,播放音频之前先要设置AVAudioSession模式,通常只用来播放的App可以设为AVAudioSessionCategoryPlayback即可。模式意义及其他模式请参考文档。
1 //后台播放音频设置
2 AVAudioSession *session = [AVAudioSession sharedInstance];
3 [session setActive:YES error:nil];
4 [session setCategory:AVAudioSessionCategoryPlayback error:nil];
1.通知IOS该app支持background audio。缺省情况下,当按下home键时,当前正在运行的程序被suspend,状态从active变成in-active,也就是说如果正在播放音频,按下HOME后就会停止。这里需要让app在按在HOME后,转到后台运行而非被suspend,解决办法是在程序的-info.plist中增加required background modes这个key项,并选择App plays audio or streams audio/video using AirPlay这个value项(如果用过Xcode5.0,在TARGETS-Capabilities-Background Modes设置为ON,勾选Audio and AirPlay选项)。
2.如果你在后台播放使用的时加载网络音频,恰巧网速很慢,音频被停止下来这时候程序也随之suspend,曾经有山寨的解决办法是专门起一个player的实例连续不停的放同一无声音片断,阻止程序被suspend。这里提供的方法是通过申请后台taskID达到后台切换播放文件的功能。
即使声明taskID也最多只能在后台运行600秒钟。(在ios7sdk中可以使用NSURLSession来实现后台缓冲)
(一般情况下,按HOME将程序送到后台,可以有5或10秒时间可以进行一些收尾工作,具体时间[[UIApplication sharedApplication] backgroundTimeRemaining]返回值,超时后app会被suspend。)
3.ipod播放程序在后台时,双击HOME键,会有个控制界面,可以对它进行播放控制(暂停开始、上一曲、下一曲)。如果您想让您的app可以像ipod一样在后台也可以方便的通过双击HOME键来控制(在ios7中是使用上拉菜单控制),就要用到远程控制事件了。
首先在viewdidload等初始化的地方声明App接收远程控制事件,并在相应地方结束声明
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
- (void) viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
}
- (BOOL)canBecomeFirstResponder
{
return YES;
}
当然也不一定是在viewcontroller中,也可以是在applicationDidEnterBackground:方法中开始接受远程控制,applicationDidBecomeActive:中结束接受远程控制,但是当前的appdelegate中要继承与UIResponder,因为在激活远程控制以后要把当前类变成第一响应,重写canBecomeFirstResponder方法。
最后定义 remoteControlReceivedWithEvent,处理具体的播放、暂停、前进、后退等具体事件
//重写父类方法,接受外部事件的处理
- (void) remoteControlReceivedWithEvent: (UIEvent *) receivedEvent {
if (receivedEvent.type == UIEventTypeRemoteControl) {
switch (receivedEvent.subtype) {
case UIEventSubtypeRemoteControlTogglePlayPause:
[self playAndStopSong:self.playButton];
break;
case UIEventSubtypeRemoteControlPreviousTrack:
[self playLastButton:self.lastButton];
break;
case UIEventSubtypeRemoteControlNextTrack:
[self playNextSong:self.nextButton];
break;
case UIEventSubtypeRemoteControlPlay:
[self playAndStopSong:self.playButton];
break;
case UIEventSubtypeRemoteControlPause:
[self playAndStopSong:self.playButton];
break;
default:
break;
}
}
}
其它外部事件也可通过这种方式实现,如“摇一摇”响应等。
4. 至此,您有播放App已经基本完成了,其次插拔耳机是否响应停止播放时间需要进一步研究耳机检测和声音路由切换的问题,再次不详细讲述。
5. 还有一些开发者可能会发现,有一些音视频app在定义的时候自定一些控件可以调节系统的音量大小,不需要用户调整音量按钮。经查看相关的资料总结出有两种方法:
一种是调用控件MPVolumeView在屏幕中创建一个音量条,拖动可以改变系统的音量大小。
另一种是使用MPMusicPlayerController类,可以自定义控件调整系统音量的大小(但是在ios7sdk中已经被弃用,估计以后几个版本中可能找不到这个方法了)。
MPMusicPlayerController *mpc = [MPMusicPlayerController applicationMusicPlayer];
mpc.volume = 0; //0.0~1.0
6. 在一些其他的音乐播放软件中如:酷我、qq音乐等,你会发在播放的时候,当设备锁屏以后依然可以看到用户播放的音乐名称、演唱者、专辑名称、音乐时长、专辑图片等信息。这些就需要在用户切换完歌去的时候,在程序中设置信息了。
//设置锁屏状态,显示的歌曲信息
-(void)configNowPlayingInfoCenter{
if (NSClassFromString(@"MPNowPlayingInfoCenter")) {
NSDictionary *info = [self.musicList objectAtIndex:_playIndex];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
//歌曲名称
[dict setObject:[info objectForKey:@"name"] forKey:MPMediaItemPropertyTitle];
//演唱者
[dict setObject:[info objectForKey:@"singer"] forKey:MPMediaItemPropertyArtist];
//专辑名
[dict setObject:[info objectForKey:@"album"] forKey:MPMediaItemPropertyAlbumTitle];
//专辑缩略图
UIImage *image = [UIImage imageNamed:[info objectForKey:@"image"]];
MPMediaItemArtwork *artwork = [[MPMediaItemArtwork alloc] initWithImage:image];
[dict setObject:artwork forKey:MPMediaItemPropertyArtwork];
//音乐剩余时长
[dict setObject:[NSNumber numberWithDouble:self.player.duration] forKey:MPMediaItemPropertyPlaybackDuration];
//音乐当前播放时间 在计时器中修改
//[dict setObject:[NSNumber numberWithDouble:0.0] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
//设置锁屏状态下屏幕显示播放音乐信息
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dict];
}
}
上面的if (NSClassFromString(@”MPNowPlayingInfoCenter”))语句,说是为了避免了版本兼容问题,这个API貌似只出现在5里面。
7. 下面就在计时器中不断刷新锁屏状态下的播放进度条了。
//计时器修改进度
- (void)changeProgress:(NSTimer *)sender{
if(self.player){
//当前播放时间
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[[MPNowPlayingInfoCenter defaultCenter] nowPlayingInfo]];
[dict setObject:[NSNumber numberWithDouble:self.player.currentTime] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime]; //音乐当前已经过时间
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dict];
}
}
8. 当前的很多常见的播放器都可以在锁屏状态下显示显示歌词,经过一番查找后,终于找到方法(详情: 点击查看 ),大致就是根据播放的时间和歌词显示时间,利用计时器不断的用歌词和专辑封面合成图片,达到显示歌词的效果。还有就是在屏幕变暗停止这一操作、屏幕点亮的时候开始计时器,以节省电量和cpu,有两种方法可以监听上述现象:
一种是监听内核层DarwinNotification,在Darwin中,有很多的系统事件,但apple的api文档描述这些api使用有限制,也就是灰色地带的api,所以能不用则不用;
另一种方法可以通过notify_get_state来获取com.apple.springboard.hasBlankedScreen 的状态值,通过状态值我们可以判断屏幕状态,屏幕亮或者暗系统会给出不同状态值,然后根据状态值,通过NotificationCenter发送消息通知给相应的函数处理。
1、首先,打开苹果手机上面的“设置”,进入手机的系统功能设置,如图所示。
2、进入设置功能之后,选择其中的“通用”,进入通用功能设置,如图所示。
3、进入苹果手机的通用功能设置之后,选择其中的“后台应用刷新”,并点击进入,如图所示。
4、进入之后,可以看到“后台应用刷新”功能默认是打开的状态,点击进入即可,如图所示。
5、如果是打开状态,当使用无线局域网或蜂窝移动网时,允许应用在后台刷新内容。
6、可以看到当前设置为在使用“WLAN和蜂窝移动网”时,是允许应用后台刷新的,这里选择关闭,就可以关闭所有后台运行的程序,如图所示。
7、也可以在后台应用刷新设置页面,手动关闭所有应用后面的按钮,使所有应用都不能在后台刷新,同样可以达到关闭所有后台运行程序的目的,如图所示。
最近在做番茄钟的功能。首先简单介绍一下番茄钟吧,就是25分钟工作番茄工作法。先说一下** 番茄工作法 **:
那么功能就相当于一个25分钟的闹钟,可以播放背景音乐,到点给用户提醒。
功能听起来很简单是不是?其实挺多坑的。
开发过程中遇到了2个问题。
OK,下面我们一步一步来分析并解决这两个问题。
** 首先要理解iOS系统的后台机制 **
我们都知道,苹果对APP占用硬件资源管的很严,更不要说应用后台时候的资源占用了。正常情况下,使用应用时,APP从硬盘加载到内存,开始工作;当用户按下home键,APP便被挂起,依然驻留在内存中,这种状态下,不调用苹果已开放的几种后台方法,程序便不会运行;如果在这个时候,使程序继续运行,则为后台状态;如果当前内存将要不够用时,系统会自动把之前挂起状态下的APP请出内存。所以我们看到,有些时候打开APP时,还是上次退出时的那个页面那些数据,有时则是重新从闪屏进入。
iOS系统后台机制大概可以分为5种状态
** 那么我需要的是Background模式。即APP在后台运行同时保持程序active的状态 **
首先去xCode里面设置。到info.plist中添加以下信息:
然后到Capabilities里面打开后台模式,并根据项目的要求勾选对应的功能。我这里只需要保持后台运行并且播放背景音乐及通知功能。所以就勾选了第一个和最后一个
以上这两步是告诉系统我这个APP支持后台模式,对应的环境为音频环境。
可是到这一步,APP还是不能长时间运行到后台。
为什么?我们思考一下。我们让程序支持了后台运行的模式。那么我们是不是还需要系统知道我们的程序要在后台运行多久呢?我们需要告诉系统我们期望APP在后台存活的时间。
首先声明一个属性
在进入后台的时候通过AppDelegate里面的方法:
现在就可以让我们的APP一直运行在后台啦!总结下来的思路就是:通过一个后台任务(这个任务我们也不用管,它存在的意义就是和系统去请求后台运行的一定的时间),这个时间我们不知道也不用去管,我们可以通过该时间还剩下多少判断是否继续请求时间,如此循环,我们就可以不断的请求时间来保持我们的app一直运行在后台。
接下来解决音乐在后台模式(切换到后台或者锁屏状态)下停止播放的问题。
其实很简单。
下面解释一下AVAudioSession的一些设置参数
Demo地址:
** 欢迎star!**
iOS应用的运行状态分为以下四种:
1、Not running:应用还没有启动,或者应用正在运行但是途中被系统停止。
2、Inactive:当前应用正在前台运行,但是并不接收事件(当前或许正在执行其它代码)。一般每当应用要从一个状态切换到另一个不同的状态时,中途过渡会短暂停留在此状态。
3、Active:当前应用正在前台运行,并且接收事件。这是应用正在前台运行时所处的正常状态。
4、Suspended:应用处在后台,并且已停止执行代码。系统自动的将应用移入此状态,且在此举之前不会对应用做任何通知。当处在此状态时,应用依然驻留内存但不执行任何程序代码。当系统发生低内存告警时,系统将会将处于 Suspended 状态的应用清除出内存以为正在前台运行的应用提供足够的内存。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流