- objective-c - iOS 5 : Can you override UIAppearance customisations in specific classes?
- iphone - 如何将 CGFontRef 转换为 UIFont?
- ios - 以编程方式关闭标记的信息窗口 google maps iOS
- ios - Xcode 5 - 尝试验证存档时出现 "No application records were found"
我正在构建一个将 CoreLocation 用于两个目的的应用:
首先,监控信标区域。大多数情况下,我们使用充当信标的特定硬件设备,并使用 CoreLocation 跟踪该信标连接的状态。
其次,当应用检测到与信标设备断开连接时,我们想要启动一个 GPS 进程来定位断开连接发生的位置。
在大多数情况下,信标设备的断开回调发生在应用程序处于后台时。因此,应用程序必须在后台调用 -startUpdatingLocation
来启动 GPS 跟踪。
这就是问题所在。如果 -startUpdatingLocation
调用发生在应用程序处于后台时,iOS 似乎不会启用位置后台更新。
显然,我已经正确配置了后台模式,NSLocationAlwaysUsageDescription
,将属性 _locationManager.allowsBackgroundLocationUpdates
设置为 YES
。
令人惊奇的是:如果我在前台调用 -startUpdatingLocation
然后切换到后台,则在后台时位置更新会正确发送。但是,当在后台调用 -startUpdatingLocation
时,应用程序会收到 2 或 3 个位置更新,然后永远暂停。直到我手动将应用程序带回前台,当位置更新恢复时,然后即使我再次将应用程序切换到后台,也能继续工作。
有人知道或了解我应该怎么做才能解决这个问题吗?还是 iOS 的主要限制?由于我的应用程序的要求,我确实需要在应用程序处于后台时开始定位更新(在信标退出区域的回调内)。
顺便说一句,如果你想重现这个问题是很容易的。只需在 Xcode 中创建一个空白项目并将此代码添加到默认 View Controller 。请记住启用后台模式,将描述添加到您的 info.plist 键“NSLocationAlwaysUsageDescription”。
- (void)viewDidLoad
{
[super viewDidLoad];
_locationManager = [[CLLocationManager alloc] init];
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_8_3)
_locationManager.allowsBackgroundLocationUpdates = YES;
_locationManager.delegate = self;
_locationManager.activityType = CLActivityTypeOther;
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
_locationManager.distanceFilter = kCLDistanceFilterNone;
[_locationManager requestAlwaysAuthorization];
// Creating a background task to delay the start of the startUpdatingLocation
__block UIBackgroundTaskIdentifier taskIdentifier = UIBackgroundTaskInvalid;
taskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:taskIdentifier];
}];
// Delaying the call to startUpdatingLocation 10 seconds, enough time to dismiss the application
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[_locationManager startUpdatingLocation];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] endBackgroundTask:taskIdentifier];
});
});
}
然后,通过执行一些 NSLog 来跟踪 CLLocationManager 委托(delegate),看看会发生什么。
谢谢,
最佳答案
您发布此问题已经 3 个月了。你自己想出来了吗?
我试过你的代码。我在 AppDelegate
委托(delegate)函数和 viewDidLoad
中放置了一些 NSLogs
。另外,在 AppDelegate
类中,我注销了后台剩余时间。
如果在进入后台之前调用 startUpdatingLocation
:
2016-08-18 01:22:52.355 test background GPS from StackOF[2267:745042] viewDidLoad
2016-08-18 01:22:52.376 test background GPS from StackOF[2267:745042] _locationManager.allowsBackgroundLocationUpdates = YES;
2016-08-18 01:22:52.382 test background GPS from StackOF[2267:745042] _locationManager requestAlwaysAuthorization
2016-08-18 01:22:52.410 test background GPS from StackOF[2267:745042] applicationDidBecomeActive
2016-08-18 01:22:52.469 test background GPS from StackOF[2267:745042] viewDidAppear
2016-08-18 01:23:03.361 test background GPS from StackOF[2267:745042] [_locationManager startUpdatingLocation];
2016-08-18 01:23:03.362 test background GPS from StackOF[2267:745042] start updating location, _locationManager.allowsBackgroundLocationUpdates == YES
2016-08-18 01:23:03.382 test background GPS from StackOF[2267:745042] Lat/Long: <redacted GPS coordinates>, horizontal accuracy: 65.000000
2016-08-18 01:23:03.630 test background GPS from StackOF[2267:745042] Lat/Long: <redacted GPS coordinates>, horizontal accuracy: 1743.000000
2016-08-18 01:23:03.709 test background GPS from StackOF[2267:745042] Lat/Long: <redacted GPS coordinates>, horizontal accuracy: 1743.000000
2016-08-18 01:23:03.716 test background GPS from StackOF[2267:745042] Lat/Long: <redacted GPS coordinates>, horizontal accuracy: 1743.000000
2016-08-18 01:23:03.720 test background GPS from StackOF[2267:745042] Lat/Long: <redacted GPS coordinates>, horizontal accuracy: 1743.000000
2016-08-18 01:23:03.814 test background GPS from StackOF[2267:745042] Lat/Long: <redacted GPS coordinates>, horizontal accuracy: 65.000000
2016-08-18 01:23:05.004 test background GPS from StackOF[2267:745042] inner block [[UIApplication sharedApplication] endBackgroundTask:taskIdentifier];
2016-08-18 01:23:05.005 test background GPS from StackOF[2267:745042] inner block start updating location, _locationManager.allowsBackgroundLocationUpdates == YES
2016-08-18 01:23:08.287 test background GPS from StackOF[2267:745042] applicationDidEnterBackground. Background time left: 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.000000
2016-08-18 01:23:10.319 test background GPS from StackOF[2267:745042] Lat/Long: <redacted GPS coordinates>, horizontal accuracy: 65.000000
2016-08-18 01:23:19.321 test background GPS from StackOF[2267:745042] Lat/Long: <redacted GPS coordinates>, horizontal accuracy: 65.000000
/****
Keep on polling...
****/
如果 startUpdatingLocation
在进入后台后被调用:
2016-08-18 01:34:29.023 test background GPS from StackOF[2285:747132] viewDidLoad
2016-08-18 01:34:29.030 test background GPS from StackOF[2285:747132] _locationManager.allowsBackgroundLocationUpdates = YES;
2016-08-18 01:34:29.033 test background GPS from StackOF[2285:747132] _locationManager requestAlwaysAuthorization
2016-08-18 01:34:29.047 test background GPS from StackOF[2285:747132] applicationDidBecomeActive
2016-08-18 01:34:29.104 test background GPS from StackOF[2285:747132] viewDidAppear
2016-08-18 01:34:31.612 test background GPS from StackOF[2285:747132] applicationDidEnterBackground. Background time left: 179.964144
2016-08-18 01:34:40.004 test background GPS from StackOF[2285:747132] [_locationManager startUpdatingLocation];
2016-08-18 01:34:40.006 test background GPS from StackOF[2285:747132] start updating location, _locationManager.allowsBackgroundLocationUpdates == YES
2016-08-18 01:34:40.290 test background GPS from StackOF[2285:747132] Lat/Long: <redacted GPS coordinates>, horizontal accuracy: 10.000000
2016-08-18 01:34:40.332 test background GPS from StackOF[2285:747132] Lat/Long: <redacted GPS coordinates>, horizontal accuracy: 355.117789
2016-08-18 01:34:40.336 test background GPS from StackOF[2285:747132] Lat/Long: <redacted GPS coordinates>, horizontal accuracy: 355.118536
2016-08-18 01:34:40.493 test background GPS from StackOF[2285:747132] Lat/Long: <redacted GPS coordinates>, horizontal accuracy: 355.141209
2016-08-18 01:34:40.496 test background GPS from StackOF[2285:747132] Lat/Long: <redacted GPS coordinates>, horizontal accuracy: 355.147748
2016-08-18 01:34:40.505 test background GPS from StackOF[2285:747132] Lat/Long: <redacted GPS coordinates>, horizontal accuracy: 355.148158
2016-08-18 01:34:40.507 test background GPS from StackOF[2285:747132] Lat/Long: <redacted GPS coordinates>, horizontal accuracy: 65.000000
2016-08-18 01:34:41.640 test background GPS from StackOF[2285:747132] inner block [[UIApplication sharedApplication] endBackgroundTask:taskIdentifier];
2016-08-18 01:34:41.642 test background GPS from StackOF[2285:747132] inner block start updating location, _locationManager.allowsBackgroundLocationUpdates == YES
/****
stops polling...
****/
记下后台剩余时间。如果应用程序在 CLLocationManager 开始更新位置之前进入后台,则后台剩余时间为 3 分钟。我自己也不太确定,因为我也有自己的 GPS 后台运行问题,但从这个简短的测试来看,似乎 CLLocationManager 必须在应用程序进入后台之前被调用。
这是我放置 NSLog 的地方:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(@"viewDidLoad");
_locationManager = [[CLLocationManager alloc] init];
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_8_3)
{
_locationManager.allowsBackgroundLocationUpdates = YES;
NSLog(@"_locationManager.allowsBackgroundLocationUpdates = YES;");
}
_locationManager.delegate = self;
_locationManager.activityType = CLActivityTypeOther;
_locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
_locationManager.distanceFilter = kCLDistanceFilterNone;
[_locationManager requestAlwaysAuthorization];
NSLog(@"_locationManager requestAlwaysAuthorization");
// Creating a background task to delay the start of the startUpdatingLocation
__block UIBackgroundTaskIdentifier taskIdentifier = UIBackgroundTaskInvalid;
taskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:taskIdentifier];
NSLog(@"[[UIApplication sharedApplication] endBackgroundTask:taskIdentifier];");
}];
// Delaying the call to startUpdatingLocation 10 seconds, enough time to dismiss the application
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[_locationManager startUpdatingLocation];
NSLog(@"[_locationManager startUpdatingLocation];");
if(_locationManager.allowsBackgroundLocationUpdates == YES)
{
NSLog(@"start updating location, _locationManager.allowsBackgroundLocationUpdates == YES");
}
else
{
NSLog(@"start updating location, _locationManager.allowsBackgroundLocationUpdates == NO");
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] endBackgroundTask:taskIdentifier];
NSLog(@"inner block [[UIApplication sharedApplication] endBackgroundTask:taskIdentifier];");
if(_locationManager.allowsBackgroundLocationUpdates == YES)
{
NSLog(@"inner block start updating location, _locationManager.allowsBackgroundLocationUpdates == YES");
}
else
{
NSLog(@"inner block start updating location, _locationManager.allowsBackgroundLocationUpdates == NO");
}
});
});
}
CLLocationManager
委托(delegate)函数:
-(void)locationManager:(CLLocationManager *) manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations
{
CLLocation *location = [locations firstObject];
NSLog(@"Lat/Long: %f %f, horizontal accuracy: %f",
location.coordinate.latitude,
location.coordinate.longitude,
location.horizontalAccuracy);
}
AppDelegate:
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(@"applicationDidEnterBackground. Background time left: %f", [[UIApplication sharedApplication] backgroundTimeRemaining]);
}
TL;DR:尝试在 viewDidLoad
或 AppDelegate application:didFinishLaunchingWithOptions:
中调用 startUpdatingLocation
/p>
关于ios - 在应用程序处于后台时启动 CLLocationManager 位置更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37045746/
我正在尝试获取从过去的 startposition/location 到当前移动的 currentposition/location 的距离(以米为单位)。 我确实有工作正常的currentposit
所以我有一堆绝对覆盖的 div。用户通过在叠加层上拖动来创建方形 div。如果您要创建一个 div,然后放大和缩小,div 会保持在同一位置,因为它对叠加层是绝对的,如前所述。 然而问题就出在这里。您
我想找到 View 在显示屏幕上的位置。 为此,我使用了 view.getLeft() 、view.getBottom() 、view.getRight() 等方法> , view.getTop()。
我有一个看起来像这样的 View 层次结构(基于其他答案和 Apple 的使用 UIScrollView 的高级 AutoLayout 指南): ScrollView 所需的2 个步骤是: 为 Scr
所以我有一个名为 MARKS 的表,我有这些列 STUDENT_ID, CLASSFORM_NAME, ACADEMIC_YEAR, TERM, SUBJECT_NAME, TOTAL_MARKS
我有一个问题我无法理解,请帮助: 我开发了带有图像的 html 页面,并使用 jQuery UI 帮助使它们可拖动,我将这些图像位置设置为相对位置并给出了左侧和顶部像素,这是页面的链接 http://
我正在尝试创建一个 CSS 动画,它在 sprite 表中循环播放 16 个图像,给人一种幽灵“漂浮”的错觉。动画通过在 background-position 位置之间移动以显示不同状态的幽灵来实现
我正在创建这个网站的 WebView https://nearxt.com/打开时询问位置但是当我使用此链接在 flutter 中创建 webview 时那么它就无法定位我还在应用程序中定义了位置,但
我正在以编程方式创建一个需要跨越 2 个屏幕的窗口。正在创建的窗口的大小是正确的,但窗口大约从第一个屏幕的一半开始。我可以将它拖回第一个屏幕的开头,NSWindow 非常适合。 我只需要知道在窗口的起
位置“/”的匹配叶路由没有元素。这意味着默认情况下它将呈现一个空值,从而导致一个“空”页面 //App.js File import { BrowserRouter as Router, Routes
我有一个运行 Ubuntu 和 Apache 的 VPS 例如,假设地址是:5.5.5.5 在 VPS 上,我有一个名为 eggdrop 的用户(除了我的 root 用户)。 用户 eggdrop 有
我有一个 JLabel与 ImageIcon ,我使用 setIcon() JLabel中的函数. ImageIcon然后上来,坐在我的JLabel 的文字左侧.是否有可能拥有 ImageIcon在文
我的图中有节点,它们的 xlabels 位于它们的左上方。我怎样才能改变这个位置?我希望 xlabels 正好位于节点本身的旁边。 最佳答案 xlp是你想要的属性,但它没有做任何事情。 你不能改变位置
我对基本的 VIM 功能有疑问:(我尝试谷歌搜索但找不到答案) 如何列出所有自定义功能。(我做了 :function 并且不能找到我的自定义函数) 如何获得自定义函数列表中的函数(或它们的存储位置)。
我是 PHP 的新手,虽然我一直在搜索,但我不知道该怎么做。 我知道可以使用 Location("some page") 进行重定向。我还读到,只要没有向用户显示任何内容,它就可以工作。 我想做的是:
如果在 jgrowl.css 中位置更改为“center”,我如何将其覆盖为默认值,即“top-right” $.jGrowl(data, { header: 'data', an
我需要根据用户是否滑动屏幕顶部、屏幕中间或屏幕底部来触发不同的事件。我正在尝试找出最好/最简单的方法来做到这一点,因为我很确定没有办法从 UISwipeGestureRecognizer 获取位置。
我需要枚举用delphi编写的外部应用程序中使用的类 ,因此我需要访问VMT表以获取该信息,但是我找不到任何有关如何在exe(由delphi生成)文件中找到VMT(虚拟方法表)的位置(地址)的文档。
在 D2010 (unicode) 中是否有像 Pos 这样不区分大小写的类似函数? 我知道我可以使用 Pos(AnsiUpperCase(FindString), AnsiUpperCase(Sou
我正在尝试为我的reveal.js 演示文稿制作一个标题,该标题会粘贴在屏幕顶部。标题中的内容在每张幻灯片的基础上都是动态的,因此我必须将标记放在 section 标记中。 显然,如果标记在 sect
我是一名优秀的程序员,十分优秀!