Determining if Airplane Mode is enabled on an iPhone? - iphone

UPDATE: As of some version of iOS 8 (8.3, maybe), GPS hardware can be turned on even in airplane mode (i.e., you can get GPS location even in airplane mode). This renders this question moot.
--
Is it possible to programatically determine if an iPhone is in Airplane Mode? I specifically want to know if it's in AirPlane Mode, as opposed to having (or not having) a network connection. This question has been asked a lot, but every answer I've seen has referred to Apple's Reachability code to determine if a network connection is available.
I'm writing an app that uses the iPhone's GPS. At the moment, if Airplane Mode is on and my app is launched, my location manager object still appears to exist and still appears to be giving me a (cached?) location. The little GPS icon appears in the status bar to let me know that my app is determining a location.
I want to know if the phone's in Airplane Mode so that I can not initialise the location manager object and I can change my UI to indicate to the user that GPS functionality is not available.
The GPS functionality can obviously be used regardless of network connectivity, so a lack of network connectivity strikes me as being a poor proxy for Airplane Mode. I don't appear to get any specific errors (through locationManager: didFailWithError) when in Airplane Mode, just a generic error that I'm assuming could come from a number of sources.

Similar requirements for my app, except I knew in advance that it would most likely be used in a "no cell signal" environment (camping in a remote area) and that the user might put the device in airplane mode to conserve batteries, without realizing it shuts down GPS.
Since airplane mode does not result in an didFailWithError, and locationServicesEnabled returns yes, I set a timer for 60 seconds, and if no GPS reading is returned before the timer expires, I display a message to the user telling them that GPS data can't be read, and suggest they check that airplane mode is not enabled, and that they ensure they have a clear view of the sky.

I don't know if it is possible to get this information, at least using public classes, but if what you need is to alert the user that he's in Airplane Mode, so with limited app functionality, you may set in your Info.plist file the UIRequiresPersistentWiFi property to "true". Then when Airplane mode is set you will get this message.
By the way note that this approach is better than just checking the Airplane Mode status, other than because it is system supported, as if the user enables Airplane mode and then re-enables Wi-Fi (still staying in Airplane Mode) then the system alert will not be displayed.

One solution might be to take a screenshot of the device and look at the colors present in that region. If they're orange, you're in airplane mode.

You really shouldn't be trying to check if Airplane Mode is enabled or not. What if Apple makes a change to how Airplane Mode works, where it will leave the GPS equipment enabled even when turned on? The best way to reliably detect whether GPS services are enabled is to implement the CLLocationManagerDelegate and let the APIs tell you whether GPS is available or not
Examining the NSError it may pass to you will let you know if there are problems to

Related

What else interferes with GPS in background other than Airplane Mode on iPhone

I have a GPS program the runs in the background and I thought I beta tested it thoroughly.
I recently submitted it to the App store for approval.
Since then I have inadvertently found out that Airplane Mode seems to disable the GPS stream and that there is no programatic way to tell if Airplane mode is on or not.
So I have to simply inform the user that, if it is more than 2 seconds since the last GPS fix, they should check that Airplane Mode is off. This seems a bit kludgy.
Is there a better way to do this?
AND, what else have I forgot about that can stop the GPS stream completely?
Thanks, Carmen
if it is more than 2 seconds since ..
This is a verry bad idea. When standing still at traffic signals, or for other reasons, you don't get a new location.
Either raise to 5 minutes, or better use a status bar which shows GPS is off.
No need to annoy users with messages.
what else have I forgot about that can stop the GPS stream completely?
The user disables the Location permission for your app. (But you can detect that.)
These both reasons, airplane mode and location permission disabled should be the only one from software view. (device internal causes)
Device external causes:
Of course using the device indoors, in tunnels or when having other obstructions to sky this hinders the GPS signal to be received.

Turning off GPS in background

I am using CoreLocation to determine user's location to calculate the distance and show the route on the map. To minimize battery usage I am turning off GPS after getting location and turning it on again after 1 minute. When the application is active everything works fine, but after sending it to background and turning off GPS, the app seems to be inactive at all, it doesn't output anything (using NSLog()). I have added directive to info.plist file to allow the application to run in background. When I don't turn off the GPS in background the app works as well as in foreground.
So my question is the following: does GPS always need to be turned on in background to prevent the application to be suspended or there is another workaround (because the turned GPS drains the battery)?
P.S. I am new to iOS and mobile development at all, so maybe there are some tips that I have to know.
See http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html
Apple does not support long running background task in general.
This does only work for specific tasks:
audio,
location,
voip,
newsstand-content,
external-accessory,
bluetooth-central and
bluetooth-peripheral
When you do not use any of that, your app could be suspended.
In your case ypu have specified location, but disabled the location update. Then for apple there is no reason to keep your app in background mode.

How to invoke "Turn Off Airplane Mode" notification

In many applications, such as the Mail app, if the device is in airplane mode a notification will pop up that says "Turn Off Airplane Mode or Use Wi-Fi to Access Data."
I thought that this would automatically be invoked if my app tries to access the internet, but it is not. Is there a special method to do this, or if not how can I check if the device is in airplane mode and provide a link to Settings to disable it?
If you add the UIRequiresPersistentWifi key to your Info.plist and set it to YES, then if you're in Airplane mode, you'll get the standard "Turn Off Airplane Mode..." popup on launch.
I test in my app. I find it changed. "UIRequiresPersistentWifi" => "Application uses Wi-Fi".
I hope it will help somebody.
You could use the apple's reachablity framework when you app launches to check for network connectivity. Check this out
http://developer.apple.com/library/ios/#samplecode/Reachability/Introduction/Intro.html
I have a wrapper class for reachbiltiy APIs to make it simpler to use. (ASIHTTPRequest has one as well).
https://github.com/daltoniam/GPHTTPRequest
see the GPReachablity class for checking for connectivity. As far as a dialog prompt, not sure there is a way to push to the settings app. Any questions let me know.
If you want the standard Turn Off Airplane Mode or Use Wi-Fi to Access Data [settings | ok]
Add a new property in your info.plist by clicking the + sign at the top.
The new property is called UIRequiresPersistentWiFi (this is similar to postings above, but needs to be exact otherwise it doesn't register)
Change type from String to Boolean
Change value from NO to YES
Clean and rebuild your app
Take a look at this. Apparently, Airport control was moved by Apple into a separate framework
It seems there is no standard way to notify the user to turn airplane mode back on. As you mentioned, this obviously isn't very elegant, so I assume apple deleted this feature.

how is it that CLLocationManager gets a location when Airplane Mode is ON

My app uses CLLocationManager to get location updates from the device.
I had assumed that when the device was in Airplane Mode, I would not get location updates. But I do.
The reason I assumed this is because Apple says that Airplane mode turns off Wifi, Cellular, Bluetooth, and GPS. See: http://support.apple.com/kb/ht1355
So, how is it that I'm getting a location update with a coordinate that seems reasonable?
I've developed an app that heavily uses the user location, so I had to check this and other situations.
I've learned that when all the services are off (Bluetooth, Wi-Fi, Cell Data)
CLLocationManager returns the latest known location, so, in this case, even if the device in Airplane mode it will return a location.
You can try this by getting your location, turn Airplane mode on and then go far from there, ask the location again.
TL; DR: It doesn't. It returns the latest known location.
You can manually turn WiFi back on in Airplane Mode, and possibly get a GPS fix if you wait long enough, depending on the iDevice model.

Running location services in the background on an older 3G iphone

I have a location based application that needs to run in the background. I have several iPhones that I am testing on including a older 3G. I register my app to need background location based services and everything works as advertised accept with the older 3G phone. When you press the lock button, it does an applicationWillResignActive: as expected, unfortunately the phone immediately goes into low power mode and that is that. When you have the phone tethered with the USB cable, and then press the lock button, the 3G phone stays alive and correctly reports location changes. When it is disconnected, it goes immediately into low power mode.
The strange thing is that I am pretty sure that it used to work. I want to see if anyone out there has an app running on an older iphone (3G) which registers for location services and is not immediately put into lower power mode when the lock button is pressed. If so, what am I doing wrong.
I followed all the directions, have locations in my Info.plist.
Thanks for your help!
Cheers,
Bryan
I think you are seeing expected behavior.
I noticed on a recent trip with my old 3g the Location Manager appeared to remain active only when the usb supplied power. On usb, unlocking the phone would bring the app up (google maps in this case) immediately with Location Manager active. Without usb, I had to relaunch Location Manager each time I unlocked the phone.
I strongly suspect this is safety/power-saving feature. The Location Manager sucks battery life at a startling rate, especially on older devices. By running the Location Manager continuously while on battery, you could easily flatline a user's phone without their knowledge.
I would be very leery of any design that requires the Location Manager to run continuously in the background. Test it throughly.
You don't want the economic consequences of users deciding that "when I use Bryan's app, my battery mysteriously dies" or the moral consequences of leaving someone in an emergency without a working phone.