简体   繁体   中英

Google API - NULL Pointer by getLastKnownLocation

Yesterdy my App worked perfectly but this morning it began to crash. I think the trigger was that I rebooted my Smartphone , so my APP loosed the GPS datas. I started the Debug mode and looked step by step for NULL values and I actuelly find it by this command :

    myLocation = locationManager.getLastKnownLocation(provider);

This returns a NULL object which cause to an crash when I try to use these methods :

latitude = myLocation.getLatitude();
longtitude = myLocation.getLongitude();

How can I make that my Location is not NULL in this case ? I tried to use the NETWORK_PROVIDER but then I have to use the WLAN and this is not the best way I think.Can I still catch informations with the GPS_PROVIDER without to get into a other Application which save them ?

BTW here is my Code :

public class gmapps extends FragmentActivity {

private GoogleMap googleMap;
TextView txt_street , txt_city , txt_country ;
Geocoder geocoder;
List<Address> addresses;
ImageView btn_yes;
Location myLocation;
String address , city , country;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.map);
    txt_street = (TextView)findViewById(R.id.txt_coordinates);
    txt_city = (TextView)findViewById(R.id.txt_city);
    txt_country = (TextView)findViewById(R.id.txt_country);
    btn_yes = (ImageView)findViewById(R.id.btn_yes);

    setUpIfNeeded();

}

private void setUpIfNeeded() {
    if (googleMap == null)
    {
        try{
        googleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
    }catch(Exception e){}

    if (googleMap != null)
    {
        setUpMap();
    }

  }
}

private void setUpMap() {

    googleMap.setMyLocationEnabled(true);

    LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
    Criteria criteria = new Criteria();
    String provider = locationManager.getBestProvider(criteria , true);

        myLocation = locationManager.getLastKnownLocation(provider);                // Here I get the NULL

    googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
    double latitude = myLocation.getLatitude();
    double longtitude = myLocation.getLongitude();
    LatLng latLng = new LatLng(latitude , longtitude);
    googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));

    googleMap.animateCamera(CameraUpdateFactory.zoomTo(17));


    try {
        convert_adresses(latitude,longtitude);
    } catch (IOException e) {
        e.printStackTrace();
    }

    txt_street.setText(address);
    txt_city.setText(city);
    txt_country.setText(country);

}

public void convert_adresses (double lat , double lng) throws IOException
{
    geocoder = new Geocoder(this, Locale.getDefault());
    addresses = geocoder.getFromLocation(lat, lng, 1);

    address = addresses.get(0).getAddressLine(0);
    city = addresses.get(0).getAddressLine(1);
    country = addresses.get(0).getAddressLine(2);
}

Thanks everyone !

you can put a check for null pointer like this

LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    Criteria criteria = new Criteria();

    String provider = locationManager.getBestProvider(criteria, false);

    Log.d("FlagLocation", "true");

    if (provider != null && !provider.equals("")) {
        Location location = locationManager.getLastKnownLocation(provider);
        locationManager.requestLocationUpdates(provider, 20000, 1, this);
        if (location != null) {
            double lng = location.getLongitude();
            double lat = location.getLatitude();
            double kmInLongitudeDegree = 111.320 * Math.cos(lat / 180.0
                    * Math.PI);

            double deltaLat = RADIUS / 111.1;
            double deltaLong = RADIUS / kmInLongitudeDegree;

            double minLat = lat - deltaLat;
            double maxLat = lat + deltaLat;
            double minLong = lng - deltaLong;
            double maxLong = lng + deltaLong;


        } 

Just retrieve the location from GPS provider when getLastLocation() == null. Take a look at the android documentation that does exactly what you need.

http://developer.android.com/training/location/retrieve-current.html

Let me know if you need some example code and I'll edit my answer. Hope this helps.

First you should be using the "new" LocationClent class (which is already depreciated in favor of LocationServices).

https://developer.android.com/reference/com/google/android/gms/location/LocationClient.html

Using this classes getLastLocation(), generally does a good job, but as the documentation says (see below), it can return null at times, so you must check for that.

What you should also do is make a request for location updates (see the doc referenced above), then when the device location becomes available it will call onLocationChanged(Location location) on your listener and you can then do whatever you need to do with the location that is provided.

public Location getLastLocation () 

Returns the best most recent location currently available. If a location is not available, which should happen very rarely, null will be returned. The best accuracy available while respecting the location permissions will be returned. This method provides a simplified way to get location. It is particularly well suited for applications that do not require an accurate location and that do not want to maintain extra logic for location updates.

Here is stripped down example of using the location client.

public class DeviceLocationClient implements
    GooglePlayServicesClient.ConnectionCallbacks,
    GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {

  private Context context;
  private LocationClient locationClient;
  private boolean isConnected;
  private LocationRequest request;


  @Override
  public void onLocationChanged(Location location) {
    System.out.println("got a location update");
    if (location != null ) {
      // do something with the location
    }
  }

  public DeviceLocationClient(Context context) {

    this.context = context;
    System.out.println("connecting to google play services");
    locationClient = new LocationClient(context, this, this);
    isConnected = false;
    locationClient.connect();

  }

  @Override
  public void onConnectionFailed(ConnectionResult result) {
    System.out.println("connection to google play services FAILED!");

  }

  @Override
  public void onConnected(Bundle connectionHint) {
    System.out.println("google play servies connected");
    isConnected = true;
    // locationClient.requestLocationUpdates(request, this);
    request = new LocationRequest();
    request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    request.setExpirationDuration(60 * 1000);
    request.setFastestInterval(5 * 1000);
    request.setInterval(10 * 1000);
    isConnected = true;
    requestLLocationUpdates();

  }

  @Override
  public void onDisconnected() {
    // TODO Auto-generated method stub
    System.out
        .println("google play services got disconnected - reconnecting");
    mBus.unregister(this);
    locationClient.connect();

  }

  @Subscribe
  public void onUpdateLocationRequest(UpdateLocationRequest event) {
    System.out.println("got the location request");
    request = new LocationRequest();
    request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    request.setExpirationDuration(60 * 1000);
    request.setFastestInterval(5 * 1000);
    request.setInterval(10 * 1000);
    locationClient.removeLocationUpdates(this);
    locationClient.requestLocationUpdates(request, this);
  }

  public void requestLLocationUpdates() {
    System.out.println("requesting location updates updates");

    if (isConnected) {
      System.out.println("processing request");
      System.out.println("sending latest location");
      Location lastLocation = locationClient.getLastLocation();
      if (lastLocation != null) {
        // do something with the last location
      }
      request = new LocationRequest();
      request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
      request.setExpirationDuration(60 * 1000);
      request.setFastestInterval(5 * 1000);
      request.setInterval(10 * 1000);
      System.out.println("requesting updates");
      locationClient.removeLocationUpdates(this);
      locationClient.requestLocationUpdates(request, this);
    } else {
      if (locationClient.isConnecting()) {
        System.out.println("google play services is connecting");
      } else {
        System.out
            .println("attempting to connect to google play services");
        locationClient.connect();
      }

    }
  }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM