how to use Cell tower triangulation in iphone? - iphone

In my app, I dont want to work off of location services. I want to get coordinates using Cell tower triangulation on the iphone.
Please tell me how to do this?

Use API called startMonitoringSignificantLocationChanges. From Apple docs -
startMonitoringSignificantLocationChanges service offers a significant
power savings and provides accuracy that is good enough for most
applications. It uses the device’s cellular radio to determine the
user’s location and report changes in that location, allowing the
system to manage power usage much more aggressively than it could
otherwise.
So in code this is how it would look -
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
locationManager.delegate = self;
[locationManager startMonitoringSignificantLocationChanges];

Related

How to use geo-based push notifications on iOS?

Is it possible to make use of geo-based push notifications on iOS when the application is killed (not in the background)?
I am interested in building an app, where the user will choose a position on a map, and then if he/she for example is close to that area a local geo-based push notification would be triggered.
However is this "idea" even possible? Can the GPS run and compare coordinates when the app is killed and run and notify the user when is in place? Is there a tutorial/article/more information of any kind on the subject that i could read?
Most of the information I read online were more like general ideas of implementing without anything specific though on the matter.
For tracking a user's location while the app is not running (ie. has previously been terminated), there are two options:
From the iOS app programming guide under "Tracking the User's Location":
The significant-change location service is highly recommended for apps that do not need high-precision location data. With this service, location updates are generated only when the user’s location changes significantly; thus, it is ideal for social apps or apps that provide the user with noncritical, location-relevant information. If the app is suspended when an update occurs, the system wakes it up in the background to handle the update. If the app starts this service and is then terminated, the system relaunches the app automatically when a new location becomes available. This service is available in iOS 4 and later, and it is available only on devices that contain a cellular radio.
However, according to the CLLocationManager class reference, it's not too accurate and updates are infrequent:
Note: Apps can expect a notification as soon as the device moves 500 meters or more from its previous notification. It should not expect notifications more frequently than once every five minutes. If the device is able to retrieve data from the network, the location manager is much more likely to deliver notifications in a timely manner.
Region Monitoring works in a similar way - including restarting the app after being terminated - but with higher accuracy (depending on availability of Wifi networks and cell towers):
The specific threshold distances are determined by the hardware and the location technologies that are currently available. For example, if Wi-Fi is disabled, region monitoring is significantly less accurate. However, for testing purposes, you can assume that the minimum distance is approximately 200 meters.
Another region monitoring consideration is that (according to the CLLocationManager class reference) region entry and exit notifications might only be received 3-5 minutes or so after crossing the region's boundaries.
Depending on the actual requirements, region monitoring could be used for obtaining a "rough" location and then when the user is within a specific region, start up the more accurate GPS based service on the location manager. When the user leaves the region of interest, turn off the GPS service to preserve battery and revert to the rough location monitoring service (ie. region monitoring) once again. Here's a basic implementation:
SomeViewController.m:
...
#interface SomeViewController () <CLLocationManagerDelegate>
#property (nonatomic, strong) CLLocationManager *locationManager;
#property (nonatomic, strong) CLRegion *someRegion;
#end
#implementation SomeViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
CLLocationDistance radius = 10; // 10 metre sensitivity
self.someRegion = [[CLRegion alloc] initCircularRegionWithCenter:someCoordinates radius:radius identifier:#"Smithtown Dry Cleaners"];
self.locationManager.delegate = self;
[self.locationManager startMonitoringForRegion:self.someRegion];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = 10;
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
[self.locationManager stopUpdatingLocation];
}
// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation* location = [locations lastObject];
// If the user's current location is not within the region anymore, stop updating
if ([self.someRegion containsCoordinate:location.coordinate] == NO) {
[self.locationManager stopUpdatingLocation];
}
NSString *locationData = [NSString stringWithFormat:#"latitude %+.6f, longitude %+.6f\n",
location.coordinate.latitude,
location.coordinate.longitude];
NSLog(#"%#", locationData);
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.alertBody = locationData;
localNotification.alertAction = #"Location data received";
localNotification.hasAction = YES;
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}
Remember to add the appropriate entries to the application's plist file so the app will run in the background with access to the appropriate resources:
MyApp-Info.plist:
<key>UIBackgroundModes</key>
<array>
...
<string>location</string>
</array>
<key>UIRequiredDeviceCapabilities</key>
<array>
...
<string>location-services</string>
<string>gps</string>
</array>
The above code assumes the use of iOS6 and ARC

Enable Location Services programmatically inside application on iPod Touch

I have an iOS application that uses GPS for Location Services. A user would like to use the app on an iPod Touch with an external GPS, but the problem is that the user can't enable Location Services in Settings->General Settings->Location Services for this app.
When the app is run on an iPhone, in Settings->General Settings->Location Services, the app shows up with a toggle switch to enable/disable Location Services for this app. But when the app is run on an iPod Touch, the app doesn't show up in Settings->General Settings->Location Services.
Does anyone know what I need to do programmatically to cause Location Services for this app to show up with a toggle switch in Settings->General Settings->Location Services when run on an iPod Touch?
I think that the ability comes when CLLocationManager is implemented for the first time. I'm not sure if that is what's used with an external GPS receiver but if you're getting the Lat/Long from the GPS, you can send those coordinates to the location manager.
I figured out what the problem was. I had the following code that only allowed Location Services for iPhone and not for iPod. Oops!
if([model hasPrefix:#"iPhone"]){
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.distanceFilter = 10.0f;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
self.locations = [NSMutableArray arrayWithCapacity:32];
}

Can we turn on/off the GPS programmatically in iPhone?

I want to know can we turn on/off the GPS programmatically in iPhone?
A simple example:
//Init location manager
CLLocationManager* locationManager = [ [ CLLocationManager alloc] init];
locationManager.delegate = self; //we must implement the protocol
//Choose your accuracy level
//To turn on gps (if it isn't on already)
[locationManager startUpdatingLocation];
//To turn gps off (if no other apps are listening)
[locationManager stopUpdatingLocation];
There is more than this, and you can monitor more or less accuracy, and even use wifi/ cell towers. Please read the example first for best usage.
Previous to iOS 5 the behavior was not consistent for launch of phone setting from third party application, but in iOS5 this is improved.
If we are calling startUpdatingLoaction method as below code and if location service is off,the system alert will popup and if we tap setting button,it will navigate to phone setting.
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startUpdatingLocation];
Well the GPS will be turned on if you use the CLLocationManager.
The locationmanager will first start by getting the location via triangulation and then turn the GPS to get a more precise fix.

iphone significant location event not related to cell change

i have been using the significant event location manager on ios, but it seems it does not based on cell change as claimed.
i used a simple application utilising significant location event, but i could not get a repeatable, consistent or sensitive response from the ios sdk.
i plotted the route (blue line), the cell towers(place mark) and a 1000m2 grid(blue square) on the map below.
map showing route
the route was 5000m in distance.
i drove it 3 times.
test1. received 2 sig events
test2. none
test3. received 1 sig events
before u complain that my test is too small, i have been monitoring other test routes for days and all show the inconsistent shape.
i was expecting the sig event to be based on cell tower switching. so i used a jailbreak app called 'signal' to identify what is the active cell. (NB.it is surprising which cell is active. Not what i would expect.)
From monitoring the 'signal' application, the cells switched around 6-7 times from what i noticed.
yet i did not received 6-7 sig events. So i cant see any correlation between cell switching and significant events.
so i have the following questions
Q1. what is the significant event trigger?
Q2. why are the result unreliable/inconsistent.
Q3. how can i get make my app receive consistent and sensitive significant event to 500m?
This is the code that is running in the test app
-(void)initLocationManager {
if (locationManager == nil) {
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
[locationManager stopUpdatingLocation];
[locationManager startMonitoringSignificantLocationChanges];
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self initLocationManager];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSLog(#"%#", newLocation);
[[NSNotificationCenter defaultCenter]
postNotificationName:#"PositionUpdate" object:nil];
}
-lp
Significant Location changes are determined by iOS and there is nothing you can do to change their granularity directly. Note that it's only in iOS 4 that only the cell tower locations are used. Future versions of the operating system will improve this.
But as a workaround you could switch on normal CoreLocation position updates when the app get's woken/started by a significant location change. And then once you have the perfect result, disable Location Monitoring again to allow the app to go back to hibernation.
I just did a 3 kilometer test walk in fairly-central San Francisco with my app, and got zero Significant Change location events as well. I have a toggle in my app to change to normal polling with kCLLocationAccuracyHundredMeters and got 40+ events over the same distance.
Echoing the sentiments of various other answers herein and elsewhere, I'm holding off on Significant Change until iOS 5. I think the best thing to do right now is roll-your-own business logic to poll the old Core Location way, and ratchet frequency down gradually over time (or something) to be battery friendly.
Seems like in iOS 4, Significant Change is better suited for being able to tell which end of your commute you're at than which block (or even zip code) you're on.
I'm not sure if you have already looked at this - but the WWDC 2010 session 115 (Using Core Location in iOS) might give you a better idea of the the significant location change API.

Strange GPS fix behavior on 3g iPhone

I wrote an GPS enabled iPhone App that needs about 70m accuracy. In most cases this accuracy is reached after a few seconds waiting. But on some occasions it is never reached. Then I have to restart the iPhone and my app and the fix is acquired immediately.
Some users also told me that starting a different app that uses gps, close that app and starting my app again fixes the problem as well. But I am not so sure if that works, because I couldn't test it myself.
The problem only occurs on 3g iPhones not on the 3gs.
Any idea what is happening or how I can fix this in code, so that I don't have to reboot my iPhone?
edit:
Code that I use:
locationManager = [[CLLocationManager alloc] init];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.delegate = self;
[locationManager startUpdatingLocation];
I'm seeing the same behavior in my own GPS-centric app. The 3G tends to narrow in more slowly than the 3GS. All I can figure so far is that the 3G's GPS got improved for the 3GS.