Android location mode, no GPS, options in AOSP - android

I'm working on an Android M STB without a GPS chip. In Android settings, Location, I get three choices for Location support -- High Accuracy, Low Bat, GPS Only. The system is defaulting to High Accuracy mode.
The problem here is that when wifi.getScanResults() is called from a background service and one of the location modes needing GPS is enabled, I don't get any results back. The call works fine from a foreground app, only background services are impacted by this. When I change the system over to Location mode Low Bat (which does not require GPS) the background getScanResults() call works as expected.
How do I modify my AOSP build so that the High Accuracy and GPS Only choices won't be presented to the user since there is no GPS chip?

Have you tried modifying the LocationManagerService class so it doesn't load a GPS provider? The following might be what you are looking for.
https://github.com/android/platform_frameworks_base/blob/nougat-release/services/core/java/com/android/server/LocationManagerService.java#L453

The default location mode is set by def_location_providers_allowed in frameworks/base/packages/SettingsProvider/res/values/defaults.xml. Its value can be either gps (GPS only), network (Battery saving) or gps,network (High accuracy).
You could therefore set def_location_providers_allowed to network (e.g. in a device/vendor overlay) and disable or hide the Mode option to the user in Settings → Location since you have only one choice (see packages/apps/Settings/res/xml/location_mode.xml).

Related

Cordova Ionic Android Location Sometimes Not Accurate

We use in Cordova with plugin "cordova-plugin-locationservices"
Sometimes we get location that a few km away from real location.
we call to "getCurrentPosition" with next options:
{
timeout: 60000,
enableHighAccuracy: true,
maximumAge: 0,
}
Someone use in this plugin and use in another options or recommend on another plugin.
At first we use "cordova-plugin-geolocation" with same options but it's also sometimes return not accurate position.
I've written extensively on this topic at https://breautek.com/articles/geolocation-accuracy.html
But to summarise there are a number of reasons why you aren't receiving the accuracy that you're after.
The two main contributors to inaccurate readings are 1) Settings & 2) The environment.
Natively, the GPS service operates in two modes: Fine location and coarse location. Fine location will allow you to get approximately up to 3-5 meter accuracy and is generally used if you require information such as the specific street. Coarse location gives you a very low accuracy reading that can only be useful to determine the location of the user's state or country.
Settings includes both programmatic settings, such as the enableHighAccuracy parameter, and they include User device settings, which is configurable by the user on based on their own location preferences.
The developer obviously has control over programmatic settings, and it looks like you're doing just that. However, the developer doesn't have access to change user preferences of the device. Just because the user has consented permission for your app to use location, doesn't mean they have location services actually enabled, or even configured to provide fine location. The specific settings can vary from device to device or by OS version to OS version. But generally speaking they usually have some sort of "Device/GPS only", and "High Accuracy" (sometimes labelled as "Bluetooth/Wifi/Mobile") setting for geolocation. It's the app's responsibility to handle these situations.
In my apps, I use the mixture of the cordova-plugin-geolocation as well as the third-party diagnostics plugin. With the diagnostics plugin, you can check if permission is granted, including for fine/precise location, as well if location services are indeed enabled.
Lastly, the second issue could be the environment. Even if the device is configured and the app has permission to use fine location, you still may not actually receive accurate readings. This can be caused purely based on the environment. Being located in a concrete office building for example hinders a lot of GPS capabilities.
It's recommended to pay attention to the accuracy field in your GPS callbacks, which will tell how confident the GPS service is that the given GPS point is accurate. The accuracy reading is in meters which tells you that the true location is within X meters radius of the given location. So in otherwords, the lower the number the better.

Why is mock location jumping back to real position

I added a test provider using LocationManager.GPS_PROVIDER as provider name like described here
https://mobiarch.wordpress.com/2012/07/17/testing-with-mock-location-data-in-android/
In Google Maps app, I see location jumping between mocked location and real location, and then back to mocked location.
Why is jumping to real location and how can I stop it?
Maybe I misunderstand how to use mock locations. I haven't found any official documentation available.
You most likely have your location settings configured in a way that your phone (and apps) can use both the location from the GPS sensor and the location from the cells and wi-fi. Since the coming of the Fused Location Provider, the way the system fetches your location got a bit murkier.
When you mock the position you are only able to mock the GPS sensor readings (this is also true for when you mock the position through the simulator settings).
So when the system feeds Google Maps with a position from the GPS sensor it gives it the fake one, and when it provides the position from other sensors it will be the real one.
To test that I'm correct, you can switch location settings to "Device only" and you should only get the fake positions.
Unfortunately there's no way to mock the other sensors readings.
Turn off Wi-Fi scanning / Bluetooth scanning in the Location Settings to stop jumping to preserve mock location.

Android gps provider and gps icon

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.

Geolocation with GPS very slow for an android app

I'm using intel xdk and cordova for an android app that uses geolocation this is the code that i use:
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(geolocalizacion,error,{enableHighAccuracy:true, maximumAge:Infinity, timeout:100000});
} else {
handleNoGeolocation(false);
}
I don't want to use the 'google location service' because, if that option is disabled, some people can get lost trying to find it in settings, so i'm using enableHighAccuracy:true in order to use GPS.
However with that it takes so much time, almost a minute to call the success function 'geolocalizacion' when the app is used indoors. I know that GPS is better in outdoors (in that case it takes 5 or 7 seconds) but i think 1 minute is too much for indoors.
Am i doing something wrong?
Is there a way to make faster the geolocation with GPS?
or a way to activate the 'google location service' without the user doing anything?.
The GPS signals transmitted by GPS satellites are very weak if you are not located outside. Even if you are outside, weather conditions, tall buildings and other large metal structures can hide or degrade the GPS signal. In addition, the GPS receivers inside of your typical phone or tablet are very low grade receivers and antennas, they are not as capable as the more expensive dedicated GPS devices, due to compromises associated price and physical size.
You should really take a two prong approach: get an initial reading using the "coarse" geo reading, with the geo cache enabled. The coarse reading will use the wifi, network, GPS and cached readings and return it's best estimate based on the parameters you specify, usually within a very reasonable time frame.
Then, after you've established an approximate position (which can be very accurate, as #SeahawksRdaBest points out, if based on the current wifi), switch to the "fine" location setting to get an accurate position. This part of your app can run in the background so it doesn't interrupt the responsiveness of your app, and can then update the position information in your app as more accurate position data becomes available.
One thing to keep in mind, many users have the GPS turned off because it severely degrades battery life. If all your app needs is to "find a restaurant nearby" then the coarse location should be good enough, since you're probably more interested in placing the destination on the map. This will be much more battery friendly, and is one of the reasons that the geo settings on the more recent Android devices have changed to make it harder for an app to enable GPS programmatically.
I see you've added the intel-xdk tag, so you might want to checkout this little geolocation test app that I've put together at https://github.com/xmnboy/hello-cordova. It needs a little work but should help you with some experimentation between coarse and fine settings.
I think you can diversify your app a little.
For example if you are indoors and have a WiFi connection why not use that to triangulate your position? WiFi is highly accurate because theoretically it covers a small space so the phone would know exactly where it is and return a position quickly.(if done right in my experience usually <10 secs).
If a Wifi connection is not found(outdoors). You can always drop back to GPS to provide the coordinates. Plus Gps is "fastest" outside anyways.
Checkout these pages: Stackoverflow discussion. Location Manager Android.
If you want to get really fancy you can even use the Geocoder Android library to get Location addresses etc in human readable form.

GPS Location returns zero speed always

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?

Categories

Resources