Google Maps can't get GPS location on Android 4.0.1 - android

My Device gps found satellite but doesn't lock. It keeps constantly trying to acquire the GPS signal, but most times it fails. I tested it on other android version 4.1.1 and the problem persists.
I just tried many combinations of resetting both Google location services and the location access and nothing fixes it. I go into maps and I can't get a gps lock at all. I've noticed, it takes longer to get a GPS signal, and the signal gays lost more often
Disabling the 'Google location services' also doesn't work
In every app that uses GPS only the empty circle shows up. Sometimes (after many seconds) the dot appears and starts blinking. But even after three minutes my phone is searching for a GPS signal.
On official google map app, It say searching for GPS signal and stays like that
I don't have any bug report.It just looking for satellites all the time, in some point there is only circle without the dot inside.
sample code used to get GPS coordinates
#Override
public void onCreate(Bundle savedInstanceState) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria c = new Criteria();
c.setAccuracy(Criteria.ACCURACY_FINE);
c.setBearingRequired(true);
pro = locationManager.getBestProvider(c, true);
locationManager.requestLocationUpdates(pro, 0, 0, this);
Location loc = locationManager.getLastKnownLocation(pro);
gpsManager = new GPSManager();
if (loc != null) {
showLocation(loc);
}
#Override
protected void onPause() {
locationManager.removeUpdates(this);
}
Is there any solution?

My favorite tool for debugging GPS issues is the GPS Test app. It shows you how many satellites your phone is detecting, how strong their signal is, how accurate the fix is, etc. This at least lets you rule out if you're in an area with bad satellite coverage.
I've only got one app on the market, but it is a GPS based app. Here's some of my code that got things working. Mind you, this only uses the GPS, it doesn't do rough location based on network.
public void initLocationManager()
{
myGpsManager = (LocationManager)getSystemService(LOCATION_SERVICE);
long time = 0;
float dist =0;
myGpsListener = new locationListener();
myGpsManager.requestLocationUpdates("gps", time, dist, myGpsListener);
}
#Override
public void onPause()
{
myGpsManager.removeUpdates(myGpsListener);
super.onPause();
}

Related

Location accuracy remains low using GPS

I have the following code in main activity:
LocationManager mlocMan = (LocationManager)getActivity().getSystemService(Context.LOCATION_SERVICE);
if (mlocMan.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
LocationListener mlocListener = new LocationManagerHelper(...);
mlocMan.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,mlocListener);
}
In the location listener I have this: (theAccuracy was initialized to -1)
if (theAccuracy == -1 || theAccuracy > loc.getAccuracy()) {
theAccuracy = Math.round(loc.getAccuracy());
latitude = loc.getLatitude();
longitude = loc.getLongitude();
}
updateTimes++;
if (updateTimes == 3) {
mLocMan.removeUpdates(this);
updateTimes = 0;
//get address for location
theAccuracy = -1;
}
Meaning, after 3 location updates from the GPS, take the best accurate location and get its address. On the emulator I get fixed accuracy of 20m (I send long/lat using DDMS) but that's not real life so I tried with my device and while the very first time (3 requests) gave me the exact address (on the spot) with 40m accuracy, the next ones were sometimes more accurate but the address was nearby. The best accuracy I got was 29m (happened once) most of the times it's above 30. Is this a problem of my GPS (LG G3) or is there any other idea that can make things more accurate after 3-4-5 requests?
A few reasons:
Your emulator doesn't have actual gps hardware, so it's probably using your ip address, so that's why it seems fixed.
GPS hardware on your phone has to warm up a bit. Set the frequency of polling up for a bit (1 update a second, or half-second), and let it run for a few seconds, before taking measurements that count.
The location manager supports both hardware and network lookups (wifi / celltowers). Not sure how to set provider to just your phone's hardware, but if you use the googlePlayServices gps client (LocationClient), it's quite simple:
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationClient.requestLocationUpdates(mLocationRequest, (LocationListener) this);
You're probably testing at your computer in doors. Buildings definitely effect gps accuracy.

activity fails on Nexus 7 but works fine on Nexus 4 & 5

I have an app that pinpoints the users location on a map. This runs successfully on both my Nexus 4 & 5, but will no longer work on my Nexus 7.
It did run on the 7, but then the device powered off during execution, and now the app will no longer work.
I have reset the device back to factory and have run all updates on it.
Here is the code from my onCreate method:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
map.setMyLocationEnabled(true);
Criteria criteria = new Criteria();
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
String provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
double lat = location.getLatitude();
double lng = location.getLongitude();
LatLng coordinate = new LatLng(lat, lng);
CameraUpdate center = CameraUpdateFactory.newLatLng(coordinate);
CameraUpdate zoom=CameraUpdateFactory.zoomTo(16);
map.moveCamera(center);
map.animateCamera(zoom);
}
It says that I am getting a NullPointerException at ** ** double lat = location.getLatitude();
I could understand an issue if it would happen on all my devices, but I can't wrap my head around why just this one device (and especially after it worked earlier)?
Per the getLastKnownLocation documentation:
If the provider is currently disabled, null is returned.
as you are using getBestProvider(criteria, false) you are saying you allow providers that are not enabled (that's what false means) - switch it to true if you only want to look at enabled providers (which will assure that getLastKnownLocation does not return null).
Note that the getLastKnownLocation could be very out of date and you may still want to look for location updates if you need to get a recent location.
There are a couple things to keep in mind when deling with gsp or network location.
*- The data takes time to arrive to your device: yes , it may take even 1 minute to recive the device 's current location. Thats why you should use a LocationListener
*-May sounds crazy but verify your smartphone is connectecd to the internet

Better way to query GPS regularly

I have a timer that runs every second. Every second I get the GPS location and do other stuffs.
I am wondering which way is better:
1- Request a single location update and then get the last known location
private void timeout(){
String data[] =new String[DATA_LENGTH];
locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, this, null);
Location loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
.
.
.
}
2- Start Location listener and then just get the last known location whenever my timer expire
OnCreate(){
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
}
private void timeout(){
String data[] =new String[DATA_LENGTH];
Location loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
.
.
.
}
Thank you
PS: Note that battery is not a concern to me as per the requirement of the product
requestSingleUpdate is meant to be single, if you need to query the GPS frequently you should definitely go with option 2.
Keep a global Location object in memory, use it in you other stuff and update it whenever your listener gets an update from the LocationManager.
You can listen for changes via requestLocationUpdates - the code below is a quick-n-dirty example (untested). Remember, you have to have location services turned on to use this.
LocationListener locGPSListener= new LocationListener() {...}
LocationListener locNetworkListener= new LocationListener() {...}
mgr = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
// listens using GPS for location
mgr .requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locGPSListener);
// uses towers for location
mgr .requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locNetworkListener);
...
What approach is better, depends on
Androids GPS behaviour and
your Application.
ad 1. if explicitly getting a location delivers a more recent fix, than this is an advantage, because:
ad 2. if your application don't want the android filtering behaviour, and you can filter it yourself better, then this would be better for your app.
Example: (is for ios, but may apply here too:) if I drive with my car to a traffic signal, and do a harsh breaking, then ios still shows 5 km/h speed, although I am standing still. This I call unwanted filtering.
This has all nothing to do with battery: if you get the location via message or if you query it is the same from battery point of view. It smore a software design issue: (events vs. polling)
A difference would only be if GPS is disabled, but disabling GPS makes only sense if it can be disabled for long time.

onlocationChanged is called even if I am sitting at the same place

I have used the code below and everything is working fine except that onLocationChanged is called even if I am sitting at the same location .
I thought it should be called only when I am moving right ?
I only want to get the location after I have moved a certain distance.
Please help me out.
Thanks in advance.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
locationMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationMgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0,
this);
}
#Override
public void onLocationChanged(Location location) {
Toast.makeText(this, "Working!", Toast.LENGTH_SHORT).show();
if (location != null) {
double lat = location.getLatitude();
double lng = location.getLongitude();
String Text = "Latitud = " + lat + "\nLongitud = " +
lng;
Toast.makeText(getBaseContext(),Text,Toast.LENGTH_SHORT).show();
}
}
You're requesting location updates at the shortest possible intervals/distances
locationMgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0,
this);
This is what the documentation says about those parameters
" The location update interval can be controlled using the minTime parameter. The elapsed time between location updates will never be less than minTime, although it can be more depending on the Location Provider implementation and the update interval requested by other applications. "
The minDistance parameter can also be used to control the frequency of location updates. If it is greater than 0 then the location provider will only send your application an update when the location has changed by at least minDistance meters, AND at least minTime milliseconds have passed. However it is more difficult for location providers to save power using the minDistance parameter, so minTime should be the primary tool to conserving battery life.
I personally use a minTime of 10 seconds and 10 meters for my app
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000,
10, locationListener);
Network location is not as precise as you would think it is. Therefore the result returned by the sensors can fluctuate. This is even more true when you consider that GPS signal weakens if you don't have direct line of sight with the satellites, and the number of visible satellites also has effect on the precision. This gets even worse when you start using the network provider, where the position is calculated by triangulation of the signal strength of cell towers, and the number and SSIDs of visible wireless network. Since these can fluctuate quite a lot, the precision suffers greatly. There are bunch of averaging algorithms, and heuristics employed to minimize such fluctuations, but ultimately nothing can stabilize it to be as good as you expect it to be.
A simple averaging and variation filtering can help you. Adding a correction based on the device accelerometer can also help a lot, but it will make your code more complex.

Android: requestLocationUpdates updates location at most every 45 seconds

Background
I am writing an Android app whose main function is tracking the user's location and making an alert when the user gets near some point. Therefore I need to update the user's location at regular intervals, and these intervals should get smaller as the user comes closer to the target. So when the user is within, say, 1 km of the target, I want the location to be updated every 20 seconds and so on, until the user arrives.
Problem
When I test it (provider = LocationManager.NETWORK_PROVIDER), a call to requestLocationUpdates(provider, minTime, minDistance, locationListener) with any minTime < 45000 has the same effect as minTime = 45000, i.e. I get updates with an interval of exactly 45 seconds.
I know the minimum time parameter is only a "hint", but it is not taken as a hint by my app. I get updates with the interval specified until that interval passes below 45 seconds. It seems as though a minimum time of 45 seconds between location updates is hardcoded into Android, but that would be kind of odd. Plus I have never heard of this problem before, and I have not been able to find it addressed here on Stackoverflow.
Because I am not able to get frequent updates, my workaround (for now) is to manually call requestLocationUpdates whenever a new location is needed, and then just use the first available location. To do this at small intervals I use handler.postDelayed(myRunnable, updateInterval) to delay the calls, and myRunnable then takes care of calling requestLocationUpdates. However, this method only works about 50 (apparently random) percent of the time.
Does anybody know of the problem, and is there a way to fix it? Or is my only option to set minTime = 0 and just hope for the best?
Source code
Here is the source code for myRunnable, whose run() method I manually call regularly with handler.postDelayed(myRunnable, updateInterval):
public class MyRunnable implements Runnable {
private LocationManager manager;
private LocationListener listener;
#Override
public void run() {
// This is called everytime a new update is requested
// so that only one request is running at a time.
removeUpdates();
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listener = new LocationListener() {
#Override
public void onLocationChanged(Location loc) {
location = loc;
latitude = loc.getLatitude();
longitude = loc.getLongitude();
accuracy = Math.round(loc.getAccuracy());
handler.sendMessage(Message.obtain(handler, KEY_MESSAGE_LOCATION_CHANGED));
checkForArrival();
}
// Other overrides are empty.
};
if(!arrived)
manager.requestLocationUpdates(provider, updateInterval, 0, listener);
}
/**
* Removes location updates from the LocationListener.
*/
public void removeUpdates() {
if(!(manager == null || listener == null))
manager.removeUpdates(listener);
}
// Another method for "cleaning up" when the user has arrived.
}
And here is my handler:
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch(msg.what) {
case KEY_MESSAGE_LOCATION_CHANGED:
if(myRunnable != null) {
myRunnable.removeUpdates();
handler.postDelayed(myRunnable, updateInterval);
}
break;
}
}
};
Additional info
The whole location updating thing runs in a service.
I have read the doc several times, Google'd the problem, and tried various other workarounds. Nothing quite does it.
I have logged the damn out of this thing, and the only exciting thing to see is a big fat "ignore" to my frequent location requests. All the right methods are called.
Any help will be very much appreciated!
You are completely right, the minimum time 45 seconds is harcoded in Android.
This seems to be a NetworkLocationProvider class source code, when it was still in Android core:
http://www.netmite.com/android/mydroid/frameworks/base/location/java/com/android/internal/location/NetworkLocationProvider.java
Look at the variable:
private static final long MIN_TIME_BETWEEN_WIFI_REPORTS = 45 * 1000; // 45 seconds
And the method:
#Override
public void setMinTime(long minTime) {
if (minTime < MIN_TIME_BETWEEN_WIFI_REPORTS) {
mWifiScanFrequency = MIN_TIME_BETWEEN_WIFI_REPORTS;
} else {
mWifiScanFrequency = minTime;
}
super.setMinTime(minTime);
}
Now NetworkLocationProvider is out of the Android core, you can find it in NetworkLocation.apk in /system/app
You can find an explanation of why is out of the core here:
https://groups.google.com/forum/?fromgroups=#!topic/android-platform/10Yr0r2myGA
But 45 seconds min time seems to still be there.
Look at this NetworkProvider decompilation:
http://android.fjfalcon.com/xt720/miui-trans/apk-decompiled/NetworkLocation/smali/com/google/android/location/NetworkLocationProvider.smali
.line 149
const-wide/32 v4, 0xafc8
iput-wide v4, p0, Lcom/google/android/location/NetworkLocationProvider;->mWifiScanFrequency:J
As you might guess if you convert 0xafc8 to decimal you get 45000 milliseconds
I haven't found an explanation of why 45 seconds. I suppose there will be reasons like avoiding service overloading or other uses they don't want.
In fact, there is a 100 request courtesy limit to Geolocation API:
https://developers.google.com/maps/documentation/business/geolocation/#usage_limits
But they don't seem to respect this rule in Google Maps app. If you open it and you only active network location you can notice that yout location is updated much more frequently than 45 seconds.
I noticed this line suspiciously frequent (33 times a second) in logcat when Google Maps is open:
02-20 17:12:08.204: V/LocationManagerService(1733): getAllProviders
I guess Google Maps is also calling removeUpdates() and requestLocationUpdates() again to obtain a new position.
So I think there is no fix and this is the best you can do if you want to get network locations over one in 45 seconds.
You can set the minTime to any value. However, you will only get an update once a new location is available. The network only updates every 45 sec or so on every phone I own. This seems to be a limitation of the Network Provider. If you want more frequent updates use the GPS provider. Depending on the GPS hardware you should get a maximum update rate around 4Hz.
I was having a similar issue. I put a call to locationManager.requestSingleUpdate() at the end of onLocationChanged() and it forced back to back updates. You could set a delay command then execute requestSingleUpdate, making sure to register the containing locationListener.
I was trying to create a GPS clock but the updates were inconsistent updating anywhere from 1-5 seconds or so. but it might work for another application.

Categories

Resources