Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I keep getting an inaccurate location in Android

Tags:

android

gps

my app records the gps location on a button click; however when I do it says I'm about three blocks away and is extremely inaccurate. Can you take a look at my code to see how I can improve it? Thanks

@Override
        protected Void doInBackground(Void... arg0) {
            SharedPreferences prefs = getSharedPreferences("Settings", 0);
            final String id = prefs.getString("ID", "");
            DefaultHttpClient httpclient = new DefaultHttpClient();
            HttpPost httpost = new HttpPost(
                    "http://iphone-radar.com/gps/gps_locations");

            JSONObject holder = new JSONObject();

            try {
                holder.put("id", id);
                LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
                Criteria criteria = new Criteria();
                String bestProvider = locationManager.getBestProvider(criteria,
                        false);
                LocationListener loc_listener=new LocationListener() {

                    @Override
                    public void onStatusChanged(String provider, int status, Bundle extras) {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void onProviderEnabled(String provider) {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void onProviderDisabled(String provider) {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void onLocationChanged(Location location) {
                        // TODO Auto-generated method stub

                    }
                };
                try{
                    Looper.prepare();
                locationManager.requestLocationUpdates(bestProvider, 0, 0, loc_listener);
                }catch(Exception e){
                    e.printStackTrace();
                }
                Location location=locationManager.

getLastKnownLocation(bestProvider);
            Calendar c = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("hh:mmaa dd'/'MM'/'yyyy");

            holder.put("time", sdf.format(c.getTime()));
            holder.put("time_since_epoch", System.currentTimeMillis());
            try {
                holder.put("lat", location.getLatitude());
                holder.put("lon", location.getLongitude());
            } catch (NullPointerException e) {
                try {
                    holder.put("lat", -1.0);
                    holder.put("lon", -1.0);
                } catch (JSONException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }

            StringEntity se = new StringEntity(holder.toString());
            httpost.setEntity(se);
            httpost.setHeader("Accept", "application/json");
            httpost.setHeader("Content-type", "application/json");

            ResponseHandler responseHandler = new BasicResponseHandler();
            String response = httpclient.execute(httpost, responseHandler);
            org.json.JSONObject obj;

                obj = new org.json.JSONObject(response);

        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
like image 373
Sean Avatar asked Dec 22 '22 09:12

Sean


2 Answers

Yes there absolutely is, try adding some accuracy to your Criteria...

Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);

The default constructor for Criteria states (emphasis mine)

Constructs a new Criteria object. The new object will have no requirements on accuracy, power, or response time; will not require altitude, speed, or bearing; and will not allow monetary cost.

like image 122
Quintin Robinson Avatar answered Dec 23 '22 23:12

Quintin Robinson


There are a number of things to note here. Firstly GPS can be inaccurate for a number of reasons. One might be adverse weather conditions, another is visibility to a sufficient number of GPS satellites. The phone itself may have a poor GPS receiver. Finally, your phone may not have connected with enough satellites to get an accurate fix.

Specifically in your code you are using the getLastKnownLocation() with an unspecified Criteria, which if I recall correctly, will use any Provider. It is highly likely that the network provider is being used rather than your GPS provider. It can take a fair bit of time to establish a quality connection with a GPS signal so getLastKnownLocation will only work if you sit still for awhile with your GPS actually running (look for the satellite receiver icon in the notification bar). You should implement a specific criteria of GPS and then implement onLocationChanged to do something once the location has been determined.

like image 44
Chris Knight Avatar answered Dec 23 '22 23:12

Chris Knight