iOS后台防止被挂起(音频or定位)
2020-12-18 本文已影响0人
山已几孑
后台音频这里,网上的资料还不算过时,因此,我这也不多少了,直把代码贴在最后面了(定位的在上一篇),这里讨论一些定位后台和音频后台,测试过程中出的一些问题
实际测试过程中发现:
- 后台音频比定位理论上少省电;
- 定位比音频稳定,不会被其他音频打断;
- 定位对权限的申请比较困难,大多用户不不愿意分配始终定位的权限
-
耗电情况
两种方式均是大概,1秒的action,20-25秒的休息等待,因此实际测试耗电情况相差并不明显;
音频后台,电量情况
定位后台的耗电情况 -
稳定性,稳定性方面肯定是优先选择定位。
-
权限申请问题,后台播放无需申请,但是定位--实测中开了永久之后,前台状态---WhenInUsed,进入后台之后---申请always,还会不定时的提醒你开了永久定位,要不要关掉
起初考虑了一个方案,在先启用音频,当音频被干掉的时候,再启用定位。
- 播放音频
- 音频后台播放中存在一个通知
AVAudioSessionInterruptionNotification
,当发生中断时,会给app发送消息 - 开启定位
BUT,实操中发现,当先启动的是音频时,无法在第二个backgroundTask之后启动定位,启动音频时同步启动定位,再关掉也不行。----反过来也是不行
简单说就是要么音频,要么定位,但是无法在后台过程中切换;
别问我,我也不知道为什么
音频后台代码
空白mp3文件 1s.mp3 百度网盘链接 提取码: ny7w
- (instancetype)init
{
self = [super init];
if (self) {
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}
return self;
}
/// APP到前台的监听
- (void)applicationWillEnterForeground:(NSNotification *)notification {
// 停止音频播放
if ( [_player isPlaying]) {
[_player stop];
}
// //停止performSelector
[NSObject cancelPreviousPerformRequestsWithTarget:self];
}
/// APP进入后台的监听
- (void)applicationDidEnterBackground:(NSNotification *)notification{
[self startPlayMusic];
}
-(void)startPlayMusic{
//1.音频文件的url路径,实际开发中,用无声音乐
NSURL *url=[[NSBundle mainBundle]URLForResource:@"1s.mp3" withExtension:Nil];
//2.创建播放器(注意:一个AVAudioPlayer只能播放一个url)
if (_player == nil) {
_player = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:Nil];
}
_player.delegate = self;
//3.缓冲
[_player prepareToPlay];
// [player setCurrentTime:1];
//4.播放
[_player playAtTime:0];
AVAudioSession *session = [AVAudioSession sharedInstance];
//后台播放
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
// 取消以前的的delay执行
[NSObject cancelPreviousPerformRequestsWithTarget:self];
}
// 音频播放完成后,嵌入后台的等待时间
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
NSLog(@"audioPlayerDidFinishPlaying ");
// // 开启后台等待
NSLog(@"🎹✅ start ~~~~~~~~%lu~~~~~%@~~~~line:%d",_locationtaskIdentifier,[[NSDate alloc] init],__LINE__);
[self startBackgroundTask:[NSString stringWithFormat:@"audioPlayer%i", count++]];
// 延时25秒,继续播放
[self performSelector:@selector(setPlayerSeektoZero) withObject:nil afterDelay: 25];
}
/// 设置播放位置到开头,
- (void)setPlayerSeektoZero {
AVAudioSession *session = [AVAudioSession sharedInstance];
//后台播放
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
NSError * error;
BOOL active = [session setActive:true error:&error];
if (!active) {
// 当音频被其他音乐应用关闭时, 再次启动时会失败,这时就没办了
NSLog(@"set active falied :: %@", error.localizedDescription);
return;
}
[_player playAtTime:0];
// 停止当前的后台任务
NSLog(@"🎹⭕️ end~~~~~~~~%lu~~~~~%@~~~~line:%d",_locationtaskIdentifier,[[NSDate alloc] init],__LINE__);
[self endBack];
}