LocationManager始终发送最后一个位置

时间:2014-06-06 09:50:16

标签: android gps locationmanager geo

我参与了位置问题。我正在获得我的第一次位置,如果我尝试下一个位置,它会一直给我最后的位置。我改变了我的位置可能有时间,但有时候,我得到最后的纬度和经度。我认为,GPS不刷新。 如果我重新启动到手机并再试一次。它显示正确的位置,如果我再次尝试,它显示我最后的位置。

我正在分享我的源代码

@Override
protected void onResume() {
    super.onResume();

    if(mMap!= null)
        mMap.clear();

    LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);                
    mFragment = (SupportMapFragment) this.getSupportFragmentManager().findFragmentById(R.id.map);
    mMap = mFragment.getMap(); 
    //if(loc != null)
        //loc.reset();

    loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    if(loc != null) {
        LatLng geo = HelperUtil.getLatLng(loc);
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(geo, 18));
        mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
    }
    setListener();

}

private void setListener(){ 
    if(locationListener != null){
        clearListener();
    }
    Toast toast = Toast.makeText(this, this.getResources().getString(R.string.maps_loading), Toast.LENGTH_LONG);
    toast.show();                   
    locationListener = new CustomLocationListener();
    LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);                
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
    Handler handler=new Handler();
    handler.postDelayed(new TimeoutTask(locationListener), 15*1000);
}

private void clearListener(){
    if(locationListener != null){
        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        locationManager.removeUpdates(locationListener);
        locationListener = null;
    }
}

public class CustomLocationListener implements LocationListener {
    private boolean isCompleted = false;

    public CustomLocationListener() {}

    @Override
    public void onLocationChanged(Location location) {
        isCompleted=true;
          // Called when a new location is found by the network location provider.
          if(isBetterLocation(location, loc)){
              gotLocation(location);
          }
          clearListener();
          setUserPoint();
    }

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

    @Override
    public void onProviderEnabled(String provider) {}

    @Override
    public void onProviderDisabled(String provider) {}

    public boolean isCompleted() {
        return isCompleted;
    }
}   


     public class TimeoutTask implements Runnable {

    private CustomLocationListener listener;

    public TimeoutTask(CustomLocationListener listener) {
        this.listener=listener;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        if (listener == null || listener.isCompleted()) {
            Log.e("provider", "completed");
            System.out.println("Lat in completed= "+loc.getLatitude());
            System.out.println("Long in completed = "+loc.getLongitude());
        }
        else {
            Log.e("provider", "timeout");
            clearListener();
            setUserPoint();
        }
    }
}

protected boolean isBetterLocation(Location location, Location currentBestLocation) {
    if (currentBestLocation == null) {
        // A new location is always better than no location
        return true;
    }

    // Check whether the new location fix is newer or older
    long timeDelta = location.getTime() - currentBestLocation.getTime();
    boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
    boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
    boolean isNewer = timeDelta > 0;

    // If it's been more than two minutes since the current location, use the new location
    // because the user has likely moved
    if (isSignificantlyNewer) {
        return true;
    // If the new location is more than two minutes older, it must be worse
    } else if (isSignificantlyOlder) {
        return false;
    }

    // Check whether the new location fix is more or less accurate
    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
    boolean isLessAccurate = accuracyDelta > 0;
    boolean isMoreAccurate = accuracyDelta < 0;
    boolean isSignificantlyLessAccurate = accuracyDelta > 200;

    // Check if the old and new location are from the same provider
    boolean isFromSameProvider = isSameProvider(location.getProvider(),
            currentBestLocation.getProvider());

    // Determine location quality using a combination of timeliness and accuracy
    if (isMoreAccurate) {
        return true;
    } else if (isNewer && !isLessAccurate) {
        return true;
    } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
        return true;
    }
    return false;
}

private void gotLocation(Location location){
    loc = location;
}

请高手帮帮我。我还注意到,有时我无法获得位置并且它说超时。你的时间对我很有帮助。

4 个答案:

答案 0 :(得分:1)

为了您的关注..使用LocationClient而不是LocationManager类...

试试这样..

LocationClient locationClient; // initialize 
Location src; // It will store your location 

然后在你的onCreate方法..

locationClient = new LocationClient(this, this, this);
locationClient.connect(); // this will call OnConnected method of location client

@Override
    public void onConnectionFailed(ConnectionResult arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onConnected(Bundle arg0) {
        src = locationClient.getLastLocation();
        System.out.println("======================location 1==" + src);

        // This is your location update .. it will update each time your location is  //changed 
        LocationRequest lrequest = new LocationRequest();
        lrequest.setInterval(0);
        lrequest.setSmallestDisplacement(0);

        locationClient.requestLocationUpdates(lrequest, new LocationListener() {

            @Override
            public void onLocationChanged(Location arg0) {
                Toast.makeText(getApplicationContext(),
                        "Location is 12" + arg0.getLatitude(),
                        Toast.LENGTH_SHORT).show();


            }
        });

    }

    @Override
    public void onDisconnected() {
        // TODO Auto-generated method stub

    }

如果您使用谷歌地图并需要在谷歌地图上更新设备的位置,那么您可以使用谷歌地图方法,因为它将为您提供设备上的当前位置,而不是设备的最后位置..

试试这样..

GoogleMap myMap;

现在在Oncreate上获取你的地图参考

myMap = ((SupportMapFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.map)).getMap();
myMap.setMyLocationEnabled(true);

现在,当你需要获得位置时,请尝试这样..

Location location = new Location();
location = myMap.getMyLocation;

就是这样......你很高兴!

答案 1 :(得分:1)

您使用的网络位置无法提供正确的位置,而不是使用网络位置,您应该使用GPS位置获取当前和准确的位置。

getLastKnowLocation()方法未提供正确的当前位置,您可以参考此link

而不是使用网络位置使用GPS位置,你可以从给定的链接找到GPS位置的好例子。

http://www.androidhive.info/2012/07/android-gps-location-manager-tutorial/

答案 2 :(得分:0)

首先确保您在清单中包含以下两行代码:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

然后我会使用类似下面的内容来获取位置更新:

public class MainActivity extends FragmentActivity implements
        GooglePlayServicesClient.ConnectionCallbacks,
        GooglePlayServicesClient.OnConnectionFailedListener,
        LocationListener {
    ...
    // Global variables
    ...
    LocationClient mLocationClient;
    boolean mUpdatesRequested;
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        // Open the shared preferences
        mPrefs = getSharedPreferences("SharedPreferences",
                Context.MODE_PRIVATE);
        // Get a SharedPreferences editor
        mEditor = mPrefs.edit();
        /*
         * Create a new location client, using the enclosing class to
         * handle callbacks.
         */
        mLocationClient = new LocationClient(this, this, this);
        // Start with updates turned off
        mUpdatesRequested = false;
        ...
    }
    ...
    @Override
    protected void onPause() {
        // Save the current setting for updates
        mEditor.putBoolean("KEY_UPDATES_ON", mUpdatesRequested);
        mEditor.commit();
        super.onPause();
    }
    ...
    @Override
    protected void onStart() {
        ...
        mLocationClient.connect();
    }
    ...
    @Override
    protected void onResume() {
        /*
         * Get any previous setting for location updates
         * Gets "false" if an error occurs
         */
        if (mPrefs.contains("KEY_UPDATES_ON")) {
            mUpdatesRequested =
                    mPrefs.getBoolean("KEY_UPDATES_ON", false);

        // Otherwise, turn off location updates
        } else {
            mEditor.putBoolean("KEY_UPDATES_ON", false);
            mEditor.commit();
        }
    }
    ...
    /*
     * Called by Location Services when the request to connect the
     * client finishes successfully. At this point, you can
     * request the current location or start periodic updates
     */
    @Override
    public void onConnected(Bundle dataBundle) {
        // Display the connection status
        Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
        // If already requested, start periodic updates
        if (mUpdatesRequested) {
            mLocationClient.requestLocationUpdates(mLocationRequest, this);
        }
    }
}

我建议你看看this tutorial. 希望它可以帮助你:)

答案 3 :(得分:0)

虽然最好的选择是根据Google Play服务(http://developer.android.com/training/location/index.html)切换到新的位置API,但我在这里尝试解释错误。

在onResume()中只调用一次setListener()方法。所以听众开始倾听。但是在任何位置改变你正在清除听众。因此,您将首先获得最后一个已知位置,然后您将获得最多一个位置更新。之后,当侦听器设置为null时,您将不会获得任何更新。所以你可以通过修改TimeoutTask来修复它。

public class TimeoutTask implements Runnable {

    private CustomLocationListener listener;

    public TimeoutTask(CustomLocationListener listener) {
        this.listener = listener;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        if (listener == null || listener.isCompleted()) {
            Log.e("provider", "completed");
            System.out.println("Lat in completed= " + loc.getLatitude());
            System.out.println("Long in completed = " + loc.getLongitude());
        } else {
            Log.e("provider", "timeout");
            clearListener();
                            setUserPoint();
        }
// setting the listener again
        setListener();
    }
}