用户位置和电池消耗
Posted
技术标签:
【中文标题】用户位置和电池消耗【英文标题】:User's location and battery's consumption 【发布时间】:2012-11-30 14:21:16 【问题描述】:我正在开发一个 ios 应用程序,该应用程序专注于建筑物(校园)中的行人。我已经开发了足够好的(我相信)用户的位置更新,但是,我希望任何比我更专业的人给我一些提示,关于准确位置的建议,电池问题等。此外,是否可以停止位置更新和n秒后重新启动?是我为了节省能源而做的一个想法。目前,应用程序正在检测当前位置,但是,蓝点(用户)仍在四处移动,我不喜欢这样。有什么可以做的吗?
下面是我的 didUpdateToLocation 方法:
应用正在从文件中读取建筑物的信息(存储在设备上)
- (void)viewDidLoad
[super viewDidLoad];
if ([self checkForInternet])
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
_locationManager.distanceFilter = 10.0f;
_locationManager.desiredAccuracy = 20.0f;
[_locationManager startUpdatingLocation];
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
if (newLocation.horizontalAccuracy > manager.desiredAccuracy) return;
[self.mapView removeAnnotations:listOfAnn];
[listOfAnn removeAllObjects];
if ([manager locationServicesEnabled])
for (NSString* row in rows)
NSArray* cells = [row componentsSeparatedByString:@"\t"];
CLLocationCoordinate2D newCoord;
newCoord.latitude = [[cells objectAtIndex:5]floatValue];
newCoord.longitude = [[cells objectAtIndex:6]floatValue];
CLLocation *locB = [[CLLocation alloc] initWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.longitude];
CLLocation *centerLoc = [[CLLocation alloc] initWithLatitude:CAMPUS_LATITUDE longitude:CAMPUS_LONGITUDE];
CLLocationDistance borders = [locB distanceFromLocation:centerLoc];
if ((int)round(borders) > 500)
BuildingViewController *newBuilding = [[BuildingViewController alloc] initBuildingWithName:[cells objectAtIndex:2] coordinates:newCoord shortDescription:[cells objectAtIndex:4] image:(NSString*)[cells objectAtIndex:3] inDistance: borders];
if ([[prefs stringForKey:newBuilding.title] isEqualToString:[prefs stringForKey:@"userName"]])
[newBuilding retrieveID];
[listOfAnn addObject:newBuilding];
else
CLLocation *locA = [[CLLocation alloc] initWithLatitude:newCoord.latitude longitude:newCoord.longitude];
CLLocationDistance distance = [locA distanceFromLocation:locB];
BuildingViewController *newBuilding = [[BuildingViewController alloc] initBuildingWithName:[cells objectAtIndex:2]
coordinates:newCoord shortDescription:[cells objectAtIndex:4] image:(NSString*)[cells objectAtIndex:3]
inDistance: distance];
if ((int)round(distance) < 100 ||
[[prefs stringForKey:newBuilding.title] isEqualToString:[prefs stringForKey:@"userName"]])
[newBuilding retrieveID];
[listOfAnn addObject:newBuilding];
[self.mapView addAnnotations:listOfAnn];
【问题讨论】:
【参考方案1】:Γεια σου Παναγιώτη。
You should read the official documentation about location services
这是一个很好的指南,应该涵盖所有内容。 我将为您做一个快速回顾,并向您解释每种可用方法的优缺点,因为我已经为我们的应用程序与核心位置服务进行了广泛的合作:
在 iOS 中有 3 种不同的方式来获取用户的位置。
-
普通 GPS 位置监控器(优点:非常准确且更新迅速,缺点:电池消耗太快)
重要的定位服务(优点:非常省电,可以从后台启动应用程序,即使在进入区域后终止,不需要后台位置监控任务和权限,缺点:在确定位置和接收方面都非常不准确位置变化的更新)
区域监控(优点:非常省电,可以从后台启动应用程序,即使在输入区域后终止,无需后台位置监控任务和权限缺点:获取有关输入区域的通知不准确,最多 20地区可以通过应用监控)
因此,根据您想要的准确性,您必须选择服务。 当然,如果您采用 GPS 方式,就像您在代码中使用的那样,您应该始终在获得更新后关闭位置更新并再次请求位置,仅在一段时间后时间,否则您的应用会耗尽用户的电量。
当然,您可以随时重新启动用户的位置更新。 如果您需要在应用中的许多视图控制器中更新位置,我建议您为位置管理器创建一个单例类!
对于 GPS 监控,在您的 CoreLocation 委托方法 didUpdateToLocation 中,执行以下操作:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
NSDate* eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
//prevent Location caching... (only accepts cached data 1 minute old)
if( abs(howRecent) < 60.0)
[self.locationManager stopUpdatingLocation];
//capture the location... (this is your code)
//update location after 90 seconds again
[self performSelector:@selector(startUpdatingLocation) withObject:nil afterDelay:90];
并再次更新位置:
- (void)startUpdatingLocation
if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusAuthorized || [CLLocationManager authorizationStatus]==kCLAuthorizationStatusNotDetermined)
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
为了确保我们已经取消了 performSelector,以防用户更改 viewController,将其添加到:
- (void)viewWillDisappear:(BOOL)animated
[super viewWillDisappear:animated];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
【讨论】:
Γειά σου Λευτέρη,感谢您对这篇文章的快速回复。我已经阅读了官方文档,但感谢您再次提及这一点。我正在使用 GPS 监控,因为正如我所说,我想为用户提供准确的位置。我不能 100% 确定重要的位置服务是否能很好地满足我的需求。您知道重要位置服务的准确度吗? Panayioti,就像我提到的,重要的位置服务和区域监控都非常不准确,并且依靠 GSM 天线而不是 GPS 来找到您的位置。如果您需要准确性,那么可以使用 GPS 方法,但就像我说的,一旦您获得更新,停止 GPS 并在给定时间后重新启动它(取决于您的需要,这可能是几秒钟,几分钟, 等等)。我正在为我的原始答案中的 gps 更新添加一些额外的代码。请看一下 谢谢。你知道为什么我打电话给 [manager stopUpdatingLocation] 之后蓝点还在移动吗? ? 如果显示的是 MKMapView,这是正常的。如果您已启用显示用户的位置,MKMapView 会在内部使用 GPS。它与你初始化的 Core Location 类无关 是的。一旦新位置到达,gps 将关闭,您将其设置为在 60/或任何秒后使用 performSelector 获取新位置。这是使用 performSelector 而不是 NSTimer 完成的原因,因为我们无法知道 GPS 实际提供可接受的 GPS 位置需要多长时间,所以这就是 performSelector 方法更好的原因,因为它只会启动在我们收到位置并停用 gps 后更新。以上是关于用户位置和电池消耗的主要内容,如果未能解决你的问题,请参考以下文章
频繁调用fusedLocationProviderClient lastKnownLocation的Android电池消耗?