在打开屏幕之前,significantLocationChanges将无法工作

时间:2016-04-28 18:01:14

标签: ios objective-c core-location cllocationmanager

我正在通过重新启动应用的后台API测试位置更新。我已成功测试了访问次数和地区,并使用同一个应用程序来测试significantLocationChanges(SLC)。我运行我的应用程序,按两次回家然后滑动它以杀死它。然后我开车。我可以在不通过服务器触摸手机的情况下观察应用程序后台活动,其中(见下面的代码)单例方法sendBackgroundTestRecord将简单的状态消息上传到服务器。

当我测试访问和地区时我没有问题。然而,当我测试SLC时,在我打开手机屏幕之前没有任何反应(按下电源或主屏幕按钮一次 - 不重新运行应用程序,甚至解锁手机)。我可以在没有任何事情发生的情况下远行。我怀疑应用程序在该驱动器的某个时间收到了SLC事件,因为只要我打开手机约2秒钟,下面的代码就会执行,我可以观察服务器上的消息。

我认为这不仅仅是网络连接延迟,因为sendBackgrounTestRecord方法使用时间戳。服务器上的记录显示我打开屏幕的时间戳,而不是怀疑SLC事件被触发的时间戳。

我从未遇到过访问或地区的问题,只有SLC。顺便说一句,代码经历了许多变化,试图追逐这一点。最新的尝试(下面的代码)是将所有内容放在appDelegate中。

有什么想法吗? 提前感谢任何想法!

编辑:我添加了beginBackgroundTaskWithExpirationHandler,这也是我原来的测试。

//  AppDelegate.h

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate>
  @property (strong, nonatomic) UIWindow *window;
  @property (strong, nonatomic) CLLocationManager *locationManager;
@end



//  AppDelegate.m

#import "AppDelegate.h"
#import "clsCommon.h"
@interface AppDelegate ()
@end
@implementation AppDelegate

  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

//Ask iOS for more time to process - before we do anything else
  [clsCommon sharedInstance].backgroundTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{}];

    [[clsCommon sharedInstance] sendBackgroundTestRecord:@"didFinishLaunchingWithOptions"];

    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    if([self.locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
      [self.locationManager setAllowsBackgroundLocationUpdates:YES];
    }
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    self.locationManager.distanceFilter = kCLDistanceFilterNone;
    self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;
    self.locationManager.allowsBackgroundLocationUpdates = YES;
    self.locationManager.pausesLocationUpdatesAutomatically = NO;
    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
      [self.locationManager requestAlwaysAuthorization];
    }

    [self.locationManager startMonitoringSignificantLocationChanges];

    return YES;
  }


  - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
    [[clsCommon sharedInstance] sendBackgroundTestRecord:@"didUpdateLocations"];
    CLLocation * currentLocation = [locations objectAtIndex:0];
    if(currentLocation !=nil) {
      [[clsCommon sharedInstance] sendBackgroundTestRecord:@"didUpdateLocations curLoc not nill"];
   }

 }

@end

2 个答案:

答案 0 :(得分:1)

嗯,知道iOS如何积极地解决所有有利于电池续航的权衡,我不会感到非常惊讶。例如,&#34;面包屑的行为&#34; app(在当前位置设置100米地理围栏,在退出事件中将地理围栏移动到新位置)是非常不同的,这取决于iPhone是否一直在口袋中睡觉,或者偶尔检查锁定屏幕。

然而,在昨天回家旅行时运行与你的应用程序非常相似的应用确实为我生成了位置更新。

SLC读数之间的距离在4到14公里范围内,两个相应读数之间的最小时间间隔--14分钟。该应用程序与您的应用程序非常相似,它不包括任何网络部分,只是将事件记录到本地文件(NSLog通过stderr重定向)。另外,我没有配置与位置管理器中的SLC无关的属性,例如desiredAccuracy,distanceFIlter,activityType。我建议你从准系统应用程序开始,注意改进,这会打破它。

要检查的一件事是,处理位置更新时您的应用是否崩溃。如果它在后台发生,除非您通过Settings.app运行日志记录或检查崩溃日志,否则您将不会注意到这一点。

答案 1 :(得分:0)

self.locationManager.distanceFilter放一些距离,更适合更换电池self.locationManager.pausesLocationUpdatesAutomatically=YES;

Start Location Manager in iOS 7 from background task