Detecting whether GPS is available iPad (Internal cellular or External Bluetooth) - ios

Is it possible to actually determine with any degree of certainty whether an iPAD actually has a GPS signal. I can think of three cases
Wifi-Only IPAD
Wifi-Only IPAD with External GPS (such as the DualXGPS)
Cellular IPAD with Internal GPS
Apple documentation mentions:
Some location services require the presence of specific hardware on
the given device. For example, heading information is available only
for devices that contain a hardware compass. This class defines
several methods that you can use to determine which services are
currently available.
Are there specific calls that work specifically with a GPS only such as heading or tracking? I'm assuming perhaps only GPS devices have a heading call because the documentation says:
In iOS, a device with the appropriate hardware may also report heading
information. When the value in the headingAvailable property is YES,
you can use a location manager object to retrieve heading information.
Some previous posts suggested trying to get a lock on a very accurate GPS update
Detect if Device has GPS
How can I tell if an iOS device has a GPS?
but i was hoping for something a little more concrete these methods "feel" wishy-washy - because just because an inaccurate GPS signal would likely look like there is no GPS when the device actually has the capability. Also I would think a wifi device which can "mimic-gps" might also some how pass one of these conditions.
Thanks for any help!

The simplest answer is that you should try to use the GPS at the accuracy you need and see if you get it. And deal with the fact that you might not get this accuracy because the user is in a building, or an urban canyon, or doesn't have GPS hardware, or has turned off location services (although this can be detected).
If you get better than 100m accuracy or if the CLLocation has altitude you almost certainly have GPS hardware (but you have to wait quite some time to get a signal lock on at least 4 satellites to get altitude). If you have a cellular radio connection (see Reachability) then you have GPS hardware (except iPhone1). If you have digital compass capability then you have GPS hardware (except iPhone 3G).
Internal GPS hardware is available on all iPhone and iPad that have cellular radios (except iPhone 1, see wiki chart). If you study that chart it appears that all devices (so far) that have GPS hardware also have digital compass (magnetometer) except iPhone 3G.
Using course (as suggested here) from the CLLocation only works if the device is moving fast enough and the GPS has satellite lock. A better option would be to detect if you have a heading from the compass (magnetometer).
You can use the hardware string to determine device capabilities by hardcoding a table of what hardware has what capabilities (described here). This has to be kept updated (which means an app update) when new devices are introduced. Erica Sadun has categories for UIDevice called Capabilities and Hardware on github that attempts this, but may not be usable in the app store.
None of this will help with external plug-in GPS or external bluetooth GPS devices.

if (location.getHoricontalAccuracy()< 40) {
// for sure GPS
} else {
// no GPS or unusable bad GPS
}
you can also use speed and course, if they are valid, then they are from GPS, because It is the only sensor that can measure speed and course. (magentometer shows the current heading, which works without GPS)

Related

Can I detect that an iOS device has external GPS connected?

Is there any way to detect that an external GPS unit is connected to an iOS device (say running iOS 13)?
We're building a special-purpose app that really needs an external GPS to work well, and want to warn the user about accuracy issues if only the internal GPS is available.
(Of course, we could wait until inaccuracies occur, but by that time it's sort of too late.)
the only way I've been able to do it is to compute position updates per second. the internal gps is 1hz. The external gps that I connect to (garmin glo) is 10hz.
If anyone has a better solution I would like to know.

Significant location change doesn't work on Wifi only devices

Correct me if I'm wrong, I have two devices (iPhone), one with sim-card included and wifi connected, other doesn't have an active sim-card but connects to wifi. I was on train to test the significant location change on both devices, only the one with sim-card sent significant location change event. The one without sim-card didn't fire any event even though it still connected to Wifi.
Any link references are appreciated. IMO, does the significant location change only work with cellular data ?
I believe the significant location change updates location only when the phone swap from a cellular tower to another, so if it is not on the cellular network (without sim card) it can not detect that, and therefore cannot provide a position :)
From Apple doc:
The significant location change service is better suited for apps that want to get the user’s initial location and then only want to know when that location changes. This service requires the presence of cellular hardware and delivers events less frequently than the standard location services.
Source

In ios, is it possible to know if the GPS location is not being updated?

I'm creating an app that allows the user to navigate with a map when offline (no internet connection or wifi available), and I want to let the user know if the gps location not being updated. I know I can get the last updated location timestamp and the accuracy, but is it possible to know if the gps has no reception?
No, there's no public interface for finding out about the state of specific location hardware such as the GPS receiver.
The Location Manager abstracts all that away, so that developers can get location and accuracy information without worrying about whether the device used GPS, Wifi, iBeacons, cell tower locations, Loran-C, celestial navigation, etc. to determine the location. This is generally a very good thing because it means that your apps work on all devices regardless of whether they have GPS, and will continue to work (and maybe even work better) on new devices that might use other technology. But it also means that you don't get to ask the question "is the device receiving a GPS signal right now?"
Is it possible to know if the GPS location is not being updated?
No. It doesn't seem possible given the available API.
There are a few things about GPS to consider, if you haven't already. It is technically possible to receive a location update from CLLocationManager when you're "offline" but it will depend on several things:
If your device actually has GPS hardware. Some don't.
If you have line of sight to GPS satellites. There's a difference between GPS and A-GPS
Those true GPS updates will come much less frequently because of the way GPS works, but it should work.
... but is it possible to know if the gps has no reception
Based on the way GPS works (as best I understand it) you either turn the radio on/off (-startUpdatingLocation/-stopUpdatingLocation) with the Location Services API and you either get locations more frequently with A-GPS or infrequently with pure GPS when you don't have a network signal. I don't think the Location Services API has a way of telling you "I don't have a GPS signal at all."

Does Apple's M7 Processor support low-power GPS tracking?

Apple's new M7 co-processor is said to enable a new generation of health and fitness apps by providing continuous monitoring of movement without draining the battery.
At the iPhone 5S announcement, Apple listed support for these sensors:
Accelerometer
Gyroscope
Compass
It doesn't mention GPS hardware, but because it would make sense for me, I'd like to know if the M7 processor can also be used for low-power geo-location tracking?
The low power option is to specify that the location manager can use deferred updates. When you do this the GPS hardware (where supported) will maintain a cache of updates until it's buffer is full (or your specified max distance is exceeded) and then send a block of updates to your app in one set (saving power by not activating the app frequently).
M7 Coprocessor would not be helpful in anyway to track the location. But some apps like STRAVA run is using M7 data to monitor the motion activity and start the GPS when the motion is detected. Which is great to save the battery.

How to get the location provider name in iOS?

In Android whenever you get location object you could call "location.getProvider" on the instance to get value like "wifi". Is there something similar in iOS (CLLocation)?
The Location Awareness Programming Guide says:
The [CoreLocation] framework uses information obtained from the built-in cellular, Wi-Fi, or GPS hardware to triangulate a location fix for the device. It reports that location to your code and, depending on how you configure the service, also provides periodic updates as it receives new or improved data
Having said that, you do not have access to how precisely the CLLocationManager determined your location (other than, if you used significant change, that it probably used cell towers). You theoretically could use Reachability to see if you have Wi-Fi availability, but you have no assurances as to what mix of GPS, cellular, and Wi-Fi it used to get your location (even if you happen to have WiFi connection).
What you do have is horizontalAccuracy, which tells you approximately how accurate the location you received is. From a user's perspective, that's probably a more important piece of information.
There isn't a concept of what system provided you with the location on iOS. What you can do is check what the accuracy of the location is. Based on how precise the location is, you can probably surmise if the location was provided by a GPS signal.
The reason this isn't given is that iOS will provide you with an initial location which won't be very accurate (likely based on geo-ip or cell triangulation) and then update the location with more and more precise coordinates if GPS is available.
If your application requires the accuracy provided by a GPS chip, you can add UIRequiredDeviceCapabilities = gps to your Info.plist.

Resources