三星Galaxy2上的GPS位置不正确

时间:2012-04-03 07:30:32

标签: android gps

我正在调查三星Galaxy2(Android 2.3.5)上的GPS位置。 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;
        }
    }
}

请你帮我解决这个问题吗? 提前谢谢。

2 个答案:

答案 0 :(得分:2)

与原版Galaxy S手机不同,GS2的GPS工作正常。

从你的代码判断你正在使用getLastKnownLocation并在GPS不可用时回退到Coarse。所以我认为这正是发生的事情:   - 你要么是一个非常过时的GPS位置   - 或者是一个粗略的位置,谷歌没有很好地映射你的区域,所以它已经关闭。

您可以通过添加日志或检查提供程序以及从getLastKnownLocation()获取的非null位置对象的时间戳来检查这些假设。

答案 1 :(得分:0)

如果您检查真实设备上的位置并且您在同一地点停留,我发现自己可以从位置稍微改变一下(您也会在GPS软件中看到这一点,但不知道您正在寻找什么方向在你开车/搬家之前)。因此,位置可能略有变化,但通常不会达到50公里。您是否有其他设备可以测试它是否依赖设备来解决50公里的问题?