Incorrect GPS location on Samsung Galaxy2

ぃ、小莉子 提交于 2019-12-24 02:07:15

问题


I am investigating GPS location on Samsung Galaxy2 (Android 2.3.5). SG2 supports A-GPS, so I turned GPS, Wifi network and Sensor aiding on. It looks working well but sometimes the GPS gives completely different location more than 50km far from my current place. Also the location changes often even though I just put on the phone one spot and never touched.

I am still new to Android, so I not sure what causes this problem. Below is the source code handling GPS location.:

public class LocationMonitor extends Service implements LocationListener,Runnable {
    .... other local variables here

    Object locationUpdateNotifier= null;
    public static GeoPoint ourLocation;


    public void synchronize()
    {
        if(ourLocation == null)
        {
            ourLocation = getLastKnownLocation();
            if(ourLocation == null) return;
        }

        //Load last time we synced
        long lastSyncTime = some_value;

        if(lastSyncTime < System.currentTimeMillis()  - UPDATE_FREQ)  //UPDATE_FREQ - default 30 minutes
        {
            handler.post(new Runnable() {
                public void run() {
                    GpsPingTask pingTask = new GpsPingTask(context,String.valueOf(ourLocation.getLatitudeE6()/1E6),String.valueOf(ourLocation.getLongitudeE6()/1E6));
                    pingTask.execute((Void)null); //Send location to server
                }
            });
            lastSyncTime =  System.currentTimeMillis();
            //Save new lastSync time 
        }
    }



    public void kill()
    {
        if(locationManager !=null)
            locationManager.removeUpdates(this);
    }

     public void onLocationChanged(Location location) {
        try
        {
            //Read latitude and longitude from location
            //Create Geo point so we can get a english street name address
            ourLocation = new GeoPoint((int)(location.getLatitude()*1E6),(int)(location.getLongitude()*1E6));

            if(locationUpdateNotifier != null)
            {
                synchronized (locationUpdateNotifier) {
                    locationUpdateNotifier.notify();
                }
            }

            if(!doneFirstUpdate)
            {
                doneFirstUpdate =true;
                Log.i("LocationMointor", "LocationMonitor.onLocationChanged() done first update at 0 frequency, resetting to normal speed");
                //Set it to update at the requested frequency
                resetLocationUpdatesFreq();
            }

            startSynchronizeThread();
        }
        catch (Throwable e) {
            Log.i("LocationMointor", "LocationMonitor.onLocationChanged(): " + e);
        }
    }


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

    }

    @Override
    public void onProviderEnabled(String provider) {}

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {}


    public void setTemporaryLocationUpdateFreq(int pingFreqSecs) {

        setTemporaryLocationUpdateFreq(pingFreqSecs, 10);
    }


    public void setTemporaryLocationUpdateFreq(int pingFreqSecs, int minimumDistanceMeters) {
        if(!doneFirstUpdate)
            doneFirstUpdate =true;

        tempLocationUpdateFreq = pingFreqSecs;
        tempLocationUpdateMeters = minimumDistanceMeters;
        handler.post(new Runnable()
        {
            public void run() {
                //Turn of location updates
                if(locationManager !=null)
                    locationManager.removeUpdates(locationMonitor);
                //Restart  location updates with new frequency
                locationManager.requestLocationUpdates(getGpsMode(), UPDATE_FREQ, tempLocationUpdateMeters,locationMonitor);
                //locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, tempLocationUpdateFreq*1000, tempLocationUpdateMeters,locationMonitor);
            }
        });
    }

    private void startSynchronizeThread() {
        if(!running)
            new Thread(this).start();
    }


    public void resetLocationUpdatesFreq() {
        locationUpdateNotifier = null;
        handler.post(new Runnable()
        {
            public void run() {
                //Turn of location updates
                if(locationManager !=null) {
                    locationManager.removeUpdates(locationMonitor);
                    //Restart  location updates with default location update frequency
                    //locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MINIMUM_TIME_BETWEEN_UPDATE, MINIMUM_DISTANCECHANGE_FOR_UPDATE,locationMonitor);
                }
            }
        });
    }


    public void setLocationUpdateFreq(int pingFreqMins) {

        Log.i("LocationMointor", "LocationMonitor.setLocationUpdateFreq().mode: " + getGpsMode() + "pingFreq:" + pingFreqMins);

        //Save new frequency value
        SharedPreferences pref = context.getSharedPreferences(PREF_PING_FREQ, Context.MODE_PRIVATE);
        Editor prefEditor=  pref.edit();
        prefEditor.putInt(PREF_PING_FREQ, 10);
        prefEditor.commit();
        handler.post(new Runnable()
        {
            public void run() {
                //Turn of location updates
                if(locationManager !=null)
                    locationManager.removeUpdates(locationMonitor);
                //Restart  location updates with new piong frequency
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MINIMUM_TIME_BETWEEN_UPDATE, MINIMUM_DISTANCECHANGE_FOR_UPDATE,locationMonitor);
            }
        });

    }


    public void addUpdateNotify(Object notifyable)
    {
        this.locationUpdateNotifier = notifyable;
    }


    public GeoPoint getLastKnownLocation()
    {
        Criteria crit = new Criteria();
        //Try get last known fine location
        crit.setAccuracy(Criteria.ACCURACY_FINE);
        String provider = locationManager.getBestProvider(crit, false);
        Location loc = locationManager.getLastKnownLocation(provider);
        //If we got no location, try coarse location
        if(loc == null)
        {

            crit.setAccuracy(Criteria.ACCURACY_COARSE);
            provider = locationManager.getBestProvider(crit, false);
            loc = locationManager.getLastKnownLocation(provider);
            //If nothing, return nothing
            if(loc == null)
            {
                Log.i("LocationMointor", "LocationMonitor.getLastKnownLocation() got no location");
                return null;
            }
        }

        //Create geopoint and return it.
        GeoPoint geoPoint = new GeoPoint((int)(loc.getLatitude()*1E6),(int)(loc.getLongitude()*1E6));
        Log.i("LocationMointor", "LocationMonitor.getLastKnownLocation() got "  +geoPoint);

        return geoPoint;
    }

    @Override
    public void run() {
        running = true;
        Object pauser = new Object();
        do{
            try
            {
                synchronize();
                synchronized(pauser)
                {
                    pauser.wait(UPDATE_FREQ);
                }

            }
            catch(Throwable ex)
            {
                Log.e("LocationMointor", "LocationMonitor.run() " +ex);
            }
        }
        while(running);
    }

    public void onCreate() {
        super.onCreate();

        this.context = this;
        this.locationMonitor= this;

        handler = new Handler(); 

        //Get the location manager service
        locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);

        //Start gps to get our location  
        this.locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, UPDATE_FREQ, this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        kill();
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return mBinder;
    } 

    private final IBinder mBinder = new MyBinder();

    public class MyBinder extends Binder {
        public LocationMonitor getService() {
            return LocationMonitor.this;
        }
    }
}

Would you please help me to get over this issue? Thanks in advance.


回答1:


Unlike the original Galaxy S phone, the GS2's GPS works okay.

Judging from your code you're using getLastKnownLocation and falling back to Coarse when GPS is not available. So I think that's just what's happening: - you're getting either a very outdated GPS location - or a coarse location and Google doesn't map your area very well so it's off.

You can check these assumptions by adding logs or by checking the provider and the timestamp of the non-null location object you are getting from getLastKnownLocation().




回答2:


If you check the location on a real device and you are staying on the same spot I noticed myself that it can vary a little bit from location (you see this also in GPS software that does not know in what direction you are looking before you are driving/moving). So a slight change in the location is possible but normally not 50km. Do you have another device to test if it is device dependant that problem of the 50 km?



来源:https://stackoverflow.com/questions/9988925/incorrect-gps-location-on-samsung-galaxy2

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!