iPhone App runnung in the background terminates after 10 minutes
I am working on an app that needs to run in the background on iOS4. I want it to be a like regular Location-based app so the BackgroundMode is set to location. The application works well when it enters the background state but after 10 minutes, it stops responding anymore. Perhaps it gets suspended/terminated. What I want to do is run the application in the background forever without any time limit until the user terminates the application exclusively. Please guide me how can I achieve this. Here I am popping up local notification when the GPS updates to a new location. Some code snippest is provided here:
- (void)applicationDidEnterBackground:(UIApplication *)application {
/*
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
*/
UIApplication* app = [UIApplication sharedApplication];
// Request permission to run in the background. Provide an
// expiration handler in case the task runs long.
NSAssert(bgTask == UIBackgroundTaskInvalid, nil);
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
// Synchronize the cleanup call on the main thread in case
// the task actually finishes at around the same time.
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task.
locmanager = [[CLLocationManager alloc] init];
[locmanager setDelegate:self];
[locmanager setDesiredAccuracy:kCLLocationAccuracyBest];
locmanager.distanceFilter = 20;
[locmanager startUpdatingLocation];
NSLog(@"App staus: applicationDidEnterBackground");
// Synchronize the cleanup call on the main thread in case
// the expiration handler is fired at the same time.
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});
});
NSLog(@"backgroundTimeRemaining: %f", [[UIApplication sharedApplication] backgroundTimeRemaining]);
}
and
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
// Log the kind of accuracy we got from this
NSLog(@"Accuracy-------- %f %f", [newLocation horizontalAccuracy], [newLocation verticalAccuracy]);
CLLocationCoordinate2D loc = [newLocation coordinate];
userCurrentLocation = newLocation;
lat = loc.latitude;
lon = loc.开发者_如何转开发longitude;
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
NSDate *now = [NSDate dateWithTimeIntervalSinceNow:10];
NSLog(@"Now is %@",now);
localNotif.fireDate = now;
localNotif.timeZone = [NSTimeZone defaultTimeZone];
// Notification details
localNotif.alertBody = [NSString stringWithFormat:@"Latitude = %f, Longitude = %f", lat, lon];
// Set the action button
localNotif.alertAction = @"View";
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 1;
// Specify custom data for the notification
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:@"someValue" forKey:@"someKey"];
localNotif.userInfo = infoDict;
// Schedule the notification
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[localNotif release];
}
Plz guide me how to do this?
Your info.plist contains this stuff?
An application can declare itself as a continuous background location application. An application that needs the regular location updates offered by the standard location services may declare itself as a continuous background application. It does this by including the UIBackgroundModes key in its Info.plist file and setting the value of this key to an array containing the location string. If an application with this key is running location services when it enters the background, it is not suspended by the system. Instead, it is allowed to continue running so that it may perform location-related tasks in the background.
http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html%23//apple_ref/doc/uid/TP40007072-CH5
You don't need to do the beginBackgroundTask... (in fact you shouldn't), by signing up for location updates (see the post above this one), your application will automatically be awoken and notified of location changes. Background Tasks are for another purpose (extended downloading etc.), and you only have a limited time to do them (around 10 minutes), if you try to keep a background task open longer then that, your application will be terminated.
Basically get rid of the beginBackgroundTask stuff, and add the UIBackgroundModes -> location key to your info.plist so that you are registered to have your app notified of location changes even while in the background.
精彩评论