Hi,

I'm writing a mapping application. In simple terms, it sends some info
about the user's current location to a server when the user clicks on
a button.

I need the location to be absolutely correct, and when I first started
to implement LocationListener, I found that it often wasn't. So I've
used location.getAccuracy() to check the GPS accuracy, and warn the
user - without submitting the data - if the location isn't accurate
enough.

The code is below.

I've been trying the app outside and find that the accuracy is often
32m, 64m or even higher, even after 20 or 30 seconds. This is in
central London, in full view of the sky, on a clear day! I need it to
be below 10m.

At the same time, if I open the Maps application while standing in the
same spot, it shows my GPS location as a blue spot on the map -
suggesting the listener in Maps has perfect accuracy.

So what is the problem? Have I implemented the listener/check in the
wrong way (which feels like the likely explanation), or is it that GPS
in Android isn't good enough to write mapping applications? Does
anyone else have experience of this?

Best,
Anna

--------------------------------------------------

//cut-down version of code

public class GPSTest extends Activity {

        /** Called when the activity is first created. */
        private static final String LOG_TAG = "GPSTest";

        private Double latitude = 0.0;
        private Double longitude = 0.0;
        private String latString = "";
        private String longString = "";

        //Location items
        LocationManager locationmanager;
        LocationListener listener;
        Location location;
        private float gpsAccuracy;
        private long locationTime;
        private long currentTime;
        private long timeDifference;

        //Textview and button
        private TextView tvErrorMessage;
        private View submitButton;

        private String responseString;

        private ProgressDialog pd;
        final Handler mHandler = new Handler();
        final Runnable mUpdateResults = new Runnable() {
                public void run() {
                        pd.dismiss();
                        updateResultsInUi();
                }
        };

        private static int globalStatus = 0;
        private static final int GPS_NOT_FOUND = 1;
        private static final int GPS_OK = 2;

        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                Log.d(LOG_TAG, "onCreate");
                setContentView(R.layout.main);

                // Set up the button listeners
                findViews();
                setListeners();

                // Register with GPS, throw an error if there's a failure
                if (!testProviders()) {
                        tvErrorMessage
                                        .setText("Can't get location - check 
that GPS is turned on in
Settings");
                }
        }

        @Override
        public void onRestart() {
                super.onRestart();
                Log.d(LOG_TAG, "onRestart");
                // Register with GPS, throw an error if there's a failure
                if (!testProviders()) {
                        tvErrorMessage
                                        .setText("Can't get location - check 
that GPS is turned on in
Settings");
                }
        }

        //
**********************************************************************
        // findViews/setListeners: set up the button listeners
        //
**********************************************************************

        private void findViews() {
                Log.d(LOG_TAG, "findViews");
                submitButton = (Button) findViewById(R.id.submit_button);
                tvErrorMessage = (TextView) findViewById(R.id.tv_error);

        }

        private void setListeners() {
                Log.d(LOG_TAG, "setListeners");
                submitButton.setOnClickListener(new OnClickListener() {
                        public void onClick(View v) {
                                uploadToServer();
                                }
                        }
                });
        }


        //
**********************************************************************
        // testProviders: Register for location updates, warn if not found
        //
**********************************************************************
        public boolean testProviders() {
                Log.d(LOG_TAG, "testProviders");
                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("gps", 0, 0, listener);

                location = locationmanager.getLastKnownLocation("gps");

                if (location != null) {
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                        latString = latitude.toString();
                        longString = longitude.toString();
                        Log.d(LOG_TAG, "Location found: latitude" + latString
                                        + " and longitude " + longString);
                        return true;

                } else {
                        Log.d(LOG_TAG, "Location not found");
                        return false;
                }

        }


        //
**********************************************************************
        // uploadToServer: uploads details, handled via a background thread
        // Also checks the age and accuracy of the GPS data first
        //
**********************************************************************
        private void uploadToServer() {
                Log.d(LOG_TAG, "uploadToServer");
                pd = ProgressDialog
                                .show(
                                                this,
                                                "Uploading, please wait...",
                                                "Uploading GPS location. This 
can take several seconds. Please
be patient!",
                                                true, false);
                Thread t = new Thread() {
                        public void run() {
                                doUploadinBackground();
                                mHandler.post(mUpdateResults);
                        }
                };
                t.start();
        }

        private boolean doUploadinBackground() {
                Log.d(LOG_TAG, "doUploadinBackground");
                DefaultHttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(<##uri##>);

                // get GPS info - make sure it's sufficiently accurate
                if (location != null) {
                        // Check that the location is up-to-date and reasonably 
accurate
                        locationTime = location.getTime();
                        currentTime = System.currentTimeMillis();
                        timeDifference = (currentTime - locationTime) / 1000;

                        gpsAccuracy = location.getAccuracy();
                        int count = 0;

                        // Wait for accurate GPS data, up to a maximum of 5 
seconds before
                        // throwing an error
                        while (((timeDifference > 30) || (gpsAccuracy > 10.0))
                                        && (count < 10)) {
                                location = 
locationmanager.getLastKnownLocation("gps");
                                locationTime = location.getTime();
                                currentTime = System.currentTimeMillis();
                                timeDifference = (currentTime - locationTime) / 
1000;
                                gpsAccuracy = location.getAccuracy();
                                Log.d(LOG_TAG, "getting up to date GPS data, 
time diff = "
                                                + timeDifference + " & accuracy 
= " + gpsAccuracy
                                                + " & count = " + count);
                                try {
                                        Thread.currentThread();
                                        Thread.sleep(500);
                                } catch (InterruptedException ie) {
                                }
                                count++;
                        }

                        // No accurate GPS data? Exit here and warn the user
                        if ((timeDifference > 10) || (gpsAccuracy > 20.0)) {
                                globalStatus = GPS_NOT_FOUND;
                                return false;
                        }

                        // OK, we're here, so we have an up-to-date, accurate 
location:
                        // commit all the GPS info
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                        latString = latitude.toString();
                        longString = longitude.toString();
                        Log.d(LOG_TAG, "Location found: latitude" + latString
                                        + " and longitude " + longString);
                        Log.d(LOG_TAG, "locationTime = " + locationTime
                                        + ", currentTime = " + currentTime
                                        + ", time difference in seconds " + 
timeDifference);
                                globalStatus = GPS_OK;
                        return true;

                } else {
                        Log.d(LOG_TAG, "Location not found");
                        return false;
                }

        }

        private void updateResultsInUi() {
                // Update the UI
                if (globalStatus == GPS_NOT_FOUND) {
                        tvErrorMessage
                                        .setText("ERROR - couldn't get 
up-to-date/accurate GPS location.
Accuracy was "
                                                        + gpsAccuracy
                                                        + " meters, 
locationTime was "
                                                        + locationTime
                                                        + " and currentTime was 
"
                                                        + currentTime
                                                        + " so timeDifference 
was "
                                                        + timeDifference
                                                        + ". Please check that 
you can see the sky!");
                }  else {
                        tvErrorMessage
                                        .setText("SUCCESS - accuracy was "
                                                        + gpsAccuracy
                                                        + " meters, 
locationTime was "
                                                        + locationTime
                                                        + " and currentTime was 
"
                                                        + currentTime
                                                        + " so timeDifference 
was "
                                                        + timeDifference
                                                        + ". Please check that 
you can see the sky!");
                }
        }

        //
**********************************************************************
        // onPause: unregister the LocationListener
        //
**********************************************************************

        @Override
        public void onPause() {
                Log.d(LOG_TAG, "onPause");
                // Unregister the LocationListener
                locationmanager.removeUpdates(listener);
                super.onPause();
        }

}



--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to