Неправилно GPS местоположение на Samsung Galaxy2

Проучвам GPS местоположението на Samsung Galaxy2 (Android 2.3.5). SG2 поддържа A-GPS, така че включих GPS, Wifi мрежа и подпомагане на сензора. Изглежда работи добре, но понякога GPS дава напълно различно местоположение на повече от 50 км от текущото ми място. Също така местоположението се променя често, въпреки че просто поставих телефона на едно място и никога не го докоснах.

Все още съм нов в Android, така че не съм сигурен какво причинява този проблем. По-долу е изходният код, обработващ GPS местоположението.:

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;
        }
    }
}

Бихте ли ми помогнали да преодолея този проблем? Благодаря предварително.


person sunghun    schedule 03.04.2012    source източник


Отговори (2)


За разлика от оригиналния телефон Galaxy S, GPS на GS2 работи добре.

Съдейки по вашия код, вие използвате getLastKnownLocation и се връщате към Coarse, когато GPS не е наличен. Така че мисля, че точно това се случва: - получавате или много остаряло GPS местоположение - или грубо местоположение и Google не картографира района ви много добре, така че е изключено.

Можете да проверите тези предположения, като добавите регистрационни файлове или като проверите доставчика и клеймото за време на ненулевия обект за местоположение, който получавате от getLastKnownLocation().

person Philippe Girolami    schedule 03.04.2012
comment
Благодаря за точката. Това е, което очаквам от тази добра общност. - person sunghun; 03.04.2012
comment
Страхотен. Не забравяйте да посочите най-добрия отговор. - person Philippe Girolami; 03.04.2012

Ако проверите местоположението на реално устройство и останете на едно и също място, забелязах, че може да се различава малко от местоположението (виждате това и в GPS софтуера, който не знае в каква посока гледате, преди да сте шофиране/движене). Така че е възможна лека промяна в местоположението, но обикновено не на 50 км. Имате ли друго устройство, за да тествате дали проблемът с 50-те километра зависи от устройството?

person TimVK    schedule 03.04.2012
comment
Скоро ще имам други устройства. - person sunghun; 03.04.2012