美文网首页
iOS后台防止被挂起(音频or定位)

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

作者: 山已几孑 | 来源:发表于2020-12-18 11:17 被阅读0次

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

    实际测试过程中发现:

    • 后台音频比定位理论上少省电;
    • 定位比音频稳定,不会被其他音频打断;
    • 定位对权限的申请比较困难,大多用户不不愿意分配始终定位的权限
    • 耗电情况
      两种方式均是大概,1秒的action,20-25秒的休息等待,因此实际测试耗电情况相差并不明显;


      音频后台,电量情况
      定位后台的耗电情况
    • 稳定性,稳定性方面肯定是优先选择定位。

    • 权限申请问题,后台播放无需申请,但是定位--实测中开了永久之后,前台状态---WhenInUsed,进入后台之后---申请always,还会不定时的提醒你开了永久定位,要不要关掉

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

    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];
    }
    

    相关文章

      网友评论

          本文标题:iOS后台防止被挂起(音频or定位)

          本文链接:https://www.haomeiwen.com/subject/wwjxnktx.html