保持app常活跃的几种方案(一直能与服务器交互,非socket)

由于项目需要,app与服务器之间需要保持一个常交互的关系。最好是app打开一次之后,在不主动杀死app的情况下,依然能与服务器交互数据。有以下几个方案:

1、GPS定位:通过一直获取地理信息,类似于百度地图的导航功能,该方法基本可以达到目的。但是受限于很多人不一定开启位置服务,而且该方法会导致耗电很快,最终没有采用。

2、音乐播放:这个就比较简单了,app中循环播放一段无声的音频,但是在锁屏状态下时会显示player界面,而且无法通过自定义移除这个界面。肯定不行也是没有采用。

3、VOIP:钉钉、QQ、微信的语音通话就是通过这个来达到不开启app情况下,唤醒接电话界面。原理就是通过voip提供的推送协议,在每次静默推送的情况下app内接受到推送消息,会给出大概10秒钟时间处理事件。通过此10s时间可以对数据进行处理和服务器交互。而且该方法可以在app杀掉进程,手机重启之后唤醒app。最后服务器可以定时几分钟给每个用户推送一次,定时唤醒app,达到心跳机制。这就是我们想要的方法。

开源代码:下载代码

源码里是第三种实现方案,如果有朋友需要前面2种的实现代码。可以在github上issues我,或者在文章后面评论,后续再补上。

补上另外2种方式的大概代码:

1:音乐播放
#import <MediaPlayer/MPNowPlayingInfoCenter.h>
@interface AppDelegate ()<AVAudioPlayerDelegate>
{
    UIBackgroundTaskIdentifier _bgTaskId;
    AVAudioPlayer *avAudioPlayer;
  }
@property (assign, nonatomic) UIBackgroundTaskIdentifier bgTask;

@property (assign, nonatomic) BOOL played;

  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterreption:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
    
        //开启后台处理多媒体事件
        [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
        AVAudioSession *session = [AVAudioSession sharedInstance];
        [session setActive:YES error:nil];
        //后台播放
        [session setCategory:AVAudioSessionCategoryPlayback error:nil];
    
        _bgTaskId = [AppDelegate backgroundPlayerID:_bgTaskId];
    
        [self playmusic];
    
        [self configNowPlayingCenter];

+(UIBackgroundTaskIdentifier)backgroundPlayerID:(UIBackgroundTaskIdentifier)backTaskId
{
    //设置并激活音频会话类别
    AVAudioSession *session=[AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategoryPlayback error:nil];
    [session setActive:YES error:nil];
    //允许应用程序接收远程控制
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    //设置后台任务ID
    UIBackgroundTaskIdentifier newTaskId = UIBackgroundTaskInvalid;
    newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
    if(newTaskId != UIBackgroundTaskInvalid && backTaskId != UIBackgroundTaskInvalid)
    {
        [[UIApplication sharedApplication] endBackgroundTask:backTaskId];
    }
    return newTaskId;
}

//处理中断事件
-(void)handleInterreption:(NSNotification *)sender
{
    if(_played)
    {
        [avAudioPlayer pause];
        _played = NO;
    }
    else
    {
        [avAudioPlayer play];
        _played = YES;
    }
}

-(void)playmusic
{
    //从budle路径下读取音频文件  这个文件名是你的歌曲名字,mp3是你的音频格式
    NSString *string = [[NSBundle mainBundle] pathForResource:@"李玉刚 - 刚好遇见你" ofType:@"mp3"];
    //把音频文件转换成url格式
    NSURL *url = [NSURL fileURLWithPath:string];
    //初始化音频类 并且添加播放文件
    avAudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
    //设置代理
    avAudioPlayer.delegate = self;
    
    //设置初始音量大小
    avAudioPlayer.volume = 1;
    
    //设置音乐播放次数  -1为一直循环
    avAudioPlayer.numberOfLoops = -1;
    
    //预播放
    //    [avAudioPlayer play];
}

-(void)configNowPlayingCenter {
    [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:nil];
}

2:GPS定位
@property (strong, nonatomic) NSTimer *timer;

    LocationManager *locationManager;
- (void)initLocation
{
    locationManager = [LocationManager shareInstance];
    
    if (![CLLocationManager locationServicesEnabled]) {
        NSLog(@"定位服务当前可能尚未打开,请设置打开!");
        return;
    }
    
    //如果没有授权则请求用户授权
    if ([CLLocationManager authorizationStatus]==kCLAuthorizationStatusNotDetermined){
        [locationManager._locationManager requestAlwaysAuthorization];
    }else if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusAuthorizedAlways){
        //设置代理
        locationManager._locationManager.delegate = self;
        //        //设置定位精度
        //        _locationManager.desiredAccuracy=kCLLocationAccuracyBest;
        //        //定位频率,每隔多少米定位一次
        //        CLLocationDistance distance= 0;//十米定位一次
        //        _locationManager.distanceFilter=distance;
        //启动跟踪定位
        [locationManager._locationManager startUpdatingLocation];
    }
}

#pragma mark  CLLocationManagerDelegate
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
    CLLocation *location=[locations firstObject];//取出第一个位置
    CLLocationCoordinate2D coordinate=location.coordinate;//位置坐标
    NSLog(@"经度:%f,纬度:%f,海拔:%f,航向:%f,行走速度:%f",coordinate.longitude,coordinate.latitude,location.altitude,location.course,location.speed);
    if (_timer == nil) {
        _timer = [NSTimer scheduledTimerWithTimeInterval:60.0f target:self selector:@selector(activeLog) userInfo:nil repeats:YES];
    }
}

复制代码
发布了149 篇原创文章 · 获赞 47 · 访问量 21万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览