iOS后台防止被挂起(音频or定位)

2020-12-18  本文已影响0人  山已几孑

后台音频这里,网上的资料还不算过时,因此,我这也不多少了,直把代码贴在最后面了(定位的在上一篇),这里讨论一些定位后台和音频后台,测试过程中出的一些问题

实际测试过程中发现:

  • 后台音频比定位理论上少省电;
  • 定位比音频稳定,不会被其他音频打断;
  • 定位对权限的申请比较困难,大多用户不不愿意分配始终定位的权限

起初考虑了一个方案,在先启用音频,当音频被干掉的时候,再启用定位。

  1. 播放音频
  2. 音频后台播放中存在一个通知AVAudioSessionInterruptionNotification,当发生中断时,会给app发送消息
  3. 开启定位

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];
}
上一篇下一篇

猜你喜欢

热点阅读