Hi there,
I'm having a weird problem with GPS accuracy.
Basically, I check the GPS accuracy in a background thread after the
user clicks a report button, and show the accuracy in a progress
dialog, changing second by second. (Code is below.) The following
strange thing happens:
1. If the user clicks more or less immediately on the button after
taking the phone out, accuracy is unsurprisingly pretty poor to start
off with, say more than 100m. But the accuracy never really improves
very much while the user is running the background thread. There is
some improvement, but it's slow and it never gets very accurate.
2. However, if the user gets the phone out and then waits for several
seconds *without* clicking on the button and running the background
thread, and *then* clicks on the button, the accuracy quickly improves
and becomes very good. When they click on the button, the accuracy
shows up as fine - within the same length of time.
So it looks as though running the background thread makes the GPS
worse. Why on earth would this happen?
This is a problem for me because my app involves sending GPS location
info off to a network service, and I check for a minimum accuracy on
the client side. Many of my users are reporting that they can't get a
GPS fix that's accurate enough. They can't get a fix that's within
tens of metres from my app even when other GPS monitoring applications
are reporting accuracy of just a few metres!
Basically my question is this - does the fact that I'm running a
background thread somehow make the accuracy worse? Or is the problem
in my code, something to do with the way that I'm polling the GPS
data?
Any thoughts very much appreciated.
Thanks
Anna
-----------
public class Home extends Activity {
// ****************************************************
// Local variables
// ****************************************************
private static final String LOG_TAG = "Home";
private Button btnReport;
// Location info
LocationManager locationmanager = null;
LocationListener listener;
Location location;
private Double latitude;
private Double longitude;
private String latString = "";
private String longString = "";
private static int globalStatus = 13;
private static final int SUCCESS = 0;
private static final int LOCATION_NOT_FOUND = 1;
private static final int LOCATION_NOT_ACCURATE = 2;
// Dialog and thread handling
private ProgressDialog pd2;
private int mSeconds = 100;
private int mProgressStatus = 300;
private Handler nHandler = new Handler();
final Runnable nUpdateResults = new Runnable() {
public void run() {
pd2.dismiss();
if (globalStatus == LOCATION_NOT_ACCURATE) {
//warn user here
} else if (globalStatus == LOCATION_NOT_FOUND) {
//warn user here
} else {
uploadToService();
}
}
};
// Called when the activity is first created
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.home);
btnReport = (Button) findViewById(R.id.report_button);
testProviders();
setListeners();
}
// Register GPS location listener etc - called when activity first
created
public void testProviders() {
// Log.e(LOG_TAG, "testProviders");
// Register for location listener
String location_context = Context.LOCATION_SERVICE;
locationmanager = (LocationManager) getSystemService
(location_context);
listener = new LocationListener() {
public void onLocationChanged(Location location) {
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status,
Bundle extras) {
}
};
locationmanager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
0,
0, listener);
if (!locationmanager.isProviderEnabled
(LocationManager.GPS_PROVIDER)) {
//warn user
}
}
// When the user clicks the report button, bring up a progress dialog
showing GPS accuracy
private void setListeners() {
btnReport.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
pd2 = ProgressDialog.show(Home.this, "Looking
for GPS fix...",
"Looking for a GPS fix", true,
false);
Thread t = new Thread() {
public void run() {
while ((mProgressStatus > 24)
|| (mSeconds > 15)) {
mProgressStatus = (int)
getGPSFix();
// Update the progress
bar
nHandler.post(new
Runnable() {
public void
run() {
pd2
.setTitle("Looking for GPS fix: accuracy now "
+ mProgressStatus + "m");
pd2
.setMessage("Looking for GPS fix: we ask for minimum 24m
accuracy, phone says last fix was approx "
+ (mSeconds + 10)
+ " seconds ago with accuracy "
+ mProgressStatus
+ "m. Please make sure you can see the sky.");
}
});
}
if ((mProgressStatus > 24) ||
(mSeconds > 15)) {
globalStatus =
LOCATION_NOT_ACCURATE;
}
nHandler.post(nUpdateResults);
}
};
t.start();
}
});
}
// Get the current GPS accuracy found by the locationmanager, return
-1 if can't be found
private float getGPSFix() {
Log.d(LOG_TAG, "getGPSFix");
if (!(locationmanager == null)) {
location = locationmanager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
if (location != null) {
// TODO - put back in
long currentTime = System.currentTimeMillis();
long gpsTime = location.getTime();
Log.d(LOG_TAG, "gpsTime = " + gpsTime + ", currentTime
= "
+ currentTime);
long timeDiffSecs = (currentTime - gpsTime) / 1000;
mSeconds = (int) timeDiffSecs;
Log.d(LOG_TAG, "timeDiffSecs = " + timeDiffSecs + ",
mSeconds = "
+ mSeconds);
latitude = location.getLatitude();
longitude = location.getLongitude();
latString = latitude.toString();
longString = longitude.toString();
Log.d(LOG_TAG, "accuracy = " + location.getAccuracy());
return location.getAccuracy();
} else {
return -1;
}
}
}
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---