I ran into a peculiar problem today: We need the users geolocation to provide our service and it is working well so far (implementation before the recent Android Location API release, have not updated it yet). We register like this
((LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE))
.requestLocationUpdates((provider == WPS)?
LocationManager.NETWORK_PROVIDER : LocationManager.GPS_PROVIDER,
minTime, minDist, onChange(ctx, provider)); // onChange create a pending intent
and on certain events we call
Location gpsLocation = LocMngr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Location wpsLocation = LocMngr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
On a HTC One S running on Android 4.0.3 and HTC Sense 4.0 we never receive location updates and the last known location returns null for gps and a 2 day old location for wps. WIFI, GPS and Mobile Data is turned on, i've tried walking around outside and saw the device trying to get a gps fix, but apparently it did not get one. Other devices have no problem with receiveing location updates from gps or wps using the same code...
This only occurs on this device (it's a test device so bootloader is locked, not rooted or any other funky stuff that might break brick it)
I am at a loss, any ideas?
UPDATE
Since we rebooted the device the problem did not occur again, I am still wondering what caused the problem...
UPDATE 2
I ran into the same Problem yesterday with a Galaxy Nexus official Android 4.2.2. So this seems to be a problem of Android in general.
Now that apparently nobody knows how to solve this, is there any way to detect when the Location API is not sending any fixes anymore? Apart from checking the timestamp of the lastKnownLocation()?
Related
I'm working on updating an existing product using here-sdk from version 3.7 to 3.8 / 3.9
It has hardware gps on board available via android LocationManager.GPS_PROVIDER, but also receives location information from an external device which is injected via location mock as the network provider:
this.locationManager.addTestProvider(LocationManager.NETWORK_PROVIDER,
false, false, false, false, true, true, true,
Criteria.POWER_LOW, Criteria.ACCURACY_FINE);
this.locationManager.setTestProviderEnabled(LocationManager.NETWORK_PROVIDER, true);
this.locationManager.setTestProviderStatus(LocationManager.NETWORK_PROVIDER,
LocationProvider.AVAILABLE, null, System.currentTimeMillis());
This external data is used primarily whenever gps is not available, eg. during startup.
PositioningManager is started with: PositioningManager.getInstance().start(PositioningManager.LocationMethod.GPS_NETWORK);
Other places in the codebase have locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, ...) -> onLocationChanged(Location location) handlers that fire on each new mocked location, plus other handlers listening to LocationManager.GPS_PROVIDER which work for updates from hardware gps.
There are also PositioningManager onPositionFixChanged() listeners which fire for these same coordinates from both providers.
On HERE SDK 3.7 this all works perfectly.
Once I upgrade HERE SDK to 3.8 however the network provider updates stop working.
The map display no longer updates and the onPositionFixChanged() listeners no longer fires for mock network updates. GPS updates work fine however.
The LocationManager onLocationChanged listeners still work for network, but not the PositioningManager callbacks.
If I change the mock provider to override LocationManager.GPS_PROVIDER instead of network, onPositionFixChanged() and the map updates correctly, but then the real gps coordinates are lost.
SDK 3.9 behaves the same.
Even changing Positioning Manager startup to not use gps, only network does not work, I get no updates from either provider then.
Switching back to 3.7 aar file makes it all work again (with no other code changes)
In case it helps, the device is running Android 5.1.1
Thanks!
I had a closer look into this topic and the root cause is here a change with the following background:
Within the 3.7 SDK we experienced an issue with the Tunnel extrapolation broken by "bad" network positions - In a simple test app a tunnel extrapolation was interrupted by a network position claim to be 24M accurate but likely was not. This is just one example but something which definitely should not happen. Within changes introduced ion 3.8 one we considered that the Android HERE We Go did not have this problem because it only uses LocationMethod.GPS during navigation and LocationMethod.GPS_NETWORK at all other times. The implementation of the same behavior means generally better navigation in tunnels is underway.
So the usage of an external device to get the location will not working starting from 3.8 and for now it is considered as expected behavior.
On the other hand it is not needed any longer as the SDK supports a much better tracking.
I am using the location service (GoogleApiClient) in my application and I have to check the received location is mock or not. I am using the location.isFromMockProvider() for checking, and it was working fine for higher version of devices with all fake gps applications.
Here I am adding the scenarios that will fail.
Take Samsung S7 (I got from S7) or any other high end device.
Install "Fake GPS Go" application and set a fake location
Check the received location (location.isFromMockProvider() returns false)
Thanks in advance.
Today when i was trying my code, a few doubtful thing appeared in my mind about gps provider, gps hardware, gps icon and fine location permission.
I observed my code and gps icon on Samsung galaxy s3, Htc one m8. And gps is disabled
mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000 * 10, 0, this, Looper.myLooper());
...
#Override
public void onLocationChanged(Location location) {
mListenerRef.get().onLocationChanged(location);
}
Galaxy s3 - Gps icon didn't appear, it didn't fire onLocationChanged method. (Thats okay)
Htc one m8 - Gps icon appeared, blinking, and fired onLocationChanged (But how ?)
At this moment questions pops up
Does ACCESS_FINE_LOCATION permission give the app override gps status on some devices?
So, could the app receive location even gps disabled ?
And then i enabled gps on galaxy s3
(First 2 minutes) Gps icon appeared(but not blinking), fired onLocationChanged method (But how ?)
(After 2 minutes) Gps icon appeared(blinking), fired onLocationChanged method
Again questions pops up
What does gps icon blinking mean ? any extracanonical meaning ?
Does the blinking mean gps hardware trying first fix ?
Or blinking means the provider firing onLocationChanged method ?
What does gps icon blinking mean?
-> Well I hope u r aware that GPS provider dosen't work under roof. So it is completely impossible to get Location update from GPS provider under roof. In such situation if user enables the GPS then the GPS blinking icon appears notifying to user that it is searching for GPS.
-> Once it finds the GPS the icon dosen't blink anymore and u'll get location updates from GPS provider.
-> A still GPS icon means Android system is ready to send location updates from GPS provider.
Htc one m8 - Gps icon appeared, blinking, and fired onLocationChanged (But how ?)
-> It sounds weird getting location updates without enabling it. I'm not sure how u confirmd that u got the Location update.
-> I'll recommend u to check if GPS provider is enabled and then request for location update.
Fine_location permission will enable user to have update from gps, wifi, network. So if gps is unavailable still onlocationChange() can be fired because a recent location may have been fetched via wifi/network.
(quote from the link: http://developer.android.com/guide/topics/location/strategies.html
Note: If you are using both NETWORK_PROVIDER and GPS_PROVIDER, then you need to request only the ACCESS_FINE_LOCATION permission, because it includes permission for both providers. (Permission for ACCESS_COARSE_LOCATION includes permission only for NETWORK_PROVIDER.
)
How your phone showed gps icon without gps being enabled, I doubt it is possible.
With HTC One (M7) the APP has permission to use the GPS and that makes 'GPS' fair game - ('GPS' = 'GPS Spoofer', AGPS [if permitted], an APP that uses WiFi and GPS [thus position is almost always immediately available], and, of course, the Phone's real Hardware GPS / GLONASS / Galileo / etc.).
The HTC UI has an Icon for the Application that uses the GPS (whatever the Phone thinks the Provider IS, a few APPs do check Provider; they don't accept spoofed Locations, EG: Most Subscription APPs, Google Play Store, abrev. GPS;) ).
A second Icon appears for the Hardware GPS. It flashes while it waits for enough Satellites. Indoors, without WiFi, with AGPS, I can get a lock in less than 1/2 min.
You probably want to check the Error when you get your LC Message, since if you're over 100 M off you don't really know where you are and probably don't have a valid position; pending calculations from one more (weak) Satellite may be enough to get you below 50 M Error, at which point you should start accepting the Location as valid (your APP might want to record Error with Coordinates, then Locations can be displayed with a circle representing the uncertainty).
When Developing you want to be certain to buy the most popular Phone (so you have real Hardware to test on, and support the greatest number of Customers), and to buy a FEW Phones with the Hardware that you want your Android APPs to control - in your case buy Phones with different GPS Hardware, for others they may need to buy a few Phones with different Camera Hardware (or WiFi Chip, etc.).
Between the Cell Phone Mfgs version of Android, their UI, and the manner in which their GPS Hardware operates (along with other APPs you have installed, like a Spoofer) you have a LOT of variables that your Program must juggle and many situations (Error Returns) that it must allow for to operate identically on as many Devices as possible.
In my application i need to show Current Lcoation every 30 minutes.To implement this, I have used Timer to trigger every 30 minutes.
It's working fine in some android devices like HTC Wildfire S, Sony Xperia V...
but it's not working in Samsung S Duos and HTC One X...Because when i request GPS it returning NULL as Current Location value.I dont' know why that devices are not support my application can anyone help with profe.
You should check for provider availability like this:
List<String> providers = locationManager.getProviders(true);
and then you start listening to available sensors:
if (providers.contains(LocationManager.GPS_PROVIDER))
{
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,...);
}
If the sensors you want are not available you should popup a dialog to user to ask him to activate the GPS, or what you want.
Also, I have a recommendation to you: you should not start requesting location updates with Timer, you should pass to requestLocationUpdates() the minimum time & distance you want location updates.
I have code that successfully gets location updates from multiple providers and filters them to give a current best estimate.
I added code to check for the returned Location.hasSpeed() and .hasBearing() values to do some bearing related calculations when the user is actually moving.
It all works fine on a Huawei Sonic running 2.3.3, but on the Google Nexus S running 4.0.4 the GPS provider's Location always returns false for .hasSpeed() and 0 for .getSpeed().
When I register my location listener, the GPS provider returns true for .supportsSpeed() but it never returns the speed in a Location even when the accuracy is down to 30m and it is physically moving (in a car, on the dashboard for max reception, screen on).
Is there some difference from 2.3.x to ICS 4.x?
Do I have to implement my own speed calculation even when the provider reports support?
Google Nexus S has history of problems with GPS. I don't think that it's specifically related to ICS. Have you tried Factory data reset the phone and then retry it?