0

I am trying to get the current location in onCreateView() in my fragment. I'm getting a null pointer exception on the line where I try to get the current longitude. What am I doing wrong?

final LocationListener locationListener = new LocationListener()
        {
            @Override
            public void onLocationChanged(Location currentLocation)
            {
                latitude = currentLocation.getLatitude();
                longitude = currentLocation.getLongitude();
            }
            public void onProviderDisabled(String provider)
            {

            }
            public void onProviderEnabled(String provider)
            {

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

            }
        };

        lm = (LocationManager)getActivity().getSystemService(Context.LOCATION_SERVICE);
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 1, locationListener);
        location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        longitude = location.getLongitude();
        latitude = location.getLatitude();
gtgaxiola
  • 9,241
  • 5
  • 42
  • 64
raginggoat
  • 3,570
  • 10
  • 48
  • 108
  • Seems that the lastKnownLocation couldn't be determined so it gives you `null`, therefore you can use any of the `Location` methods until you actually get a `Location` – gtgaxiola Apr 06 '15 at 13:08
  • possible duplicate of [Location Manager Returns Null Pointer Expection](http://stackoverflow.com/questions/23971333/location-manager-returns-null-pointer-expection) – gtgaxiola Apr 06 '15 at 13:09
  • add some logs so that it will be better to understand. – Ashish Tamrakar Apr 06 '15 at 13:10

3 Answers3

2

You are not wrong.

location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);

That method return only last known location. It does not calculate location. It will be null when there is no old location record. You request updates in your code. So if you need, you can wait till you get location update.

Hein Htet Aung
  • 844
  • 4
  • 16
1

Are you talking about the location.getLongitude() call outside of the callback? If that is what you are talking about, then there is no guarantee that a phone will have GPS or have GPS enabled. In either of those scenarious, you'll get a null response. While it is hard to cater for all scenarios, you're better off getting location from the network provider which is very likely to be there. Also, I would use a Criteria builder to get a connection more suited for your needs. For example, if you just want to know what city a user is in, GPS is over kill.

//force last known location from network provider
String providerName = LocationManager.NETWORK_PROVIDER;
if (mLocationManager.isProviderEnabled(providerName)) {
  Location lastLocation = mLocationManager.getLastKnownLocation(providerName);
}

//get high accuracy provider
providerName = mLocationManager.getBestProvider(createMediumCriteria(), true);
if (providerName == null) {
  // get low accuracy provider
  providerName = mLocationManager.getBestProvider(createLowCriteria(), true);
}

if (providerName == null) {
  //get low accuracy even if its disabled
  providerName = mLocationManager.getBestProvider(createLowCriteria(), false);
}

if (providerName != null && mLocationManager.isProviderEnabled(providerName)) {

  Location lastLocation = mLocationManager.getLastKnownLocation(providerName);

  if (lastLocation != null) {
    onLocationChanged(lastLocation);
  }
  //else {
  //timeout after 30 seconds.
  if (!sLocationHandler.hasMessages(MSG_UNREGISTER)) {
    sLocationHandler.sendEmptyMessageDelayed(MSG_UNREGISTER, 30000);
  }

  //LocationProvider provider = locMgr.getProvider(providerName);
  // using low accuracy provider... to listen for updates
  mLocationManager.requestLocationUpdates(providerName, 0, 0f, this);
  //}

The criteria builders will be something like:

  /**
   * this criteria will settle for less accuracy, high power, and cost
   */
  public static Criteria createLowCriteria() {

    Criteria c = new Criteria();
    c.setAccuracy(Criteria.ACCURACY_LOW);
    c.setAltitudeRequired(false);
    c.setBearingRequired(false);
    c.setSpeedRequired(false);
    c.setCostAllowed(true);
    c.setPowerRequirement(Criteria.POWER_LOW);
    return c;
  }

  /**
   * this criteria needs high accuracy, high power, and cost
   */
  public static Criteria createMediumCriteria() {

    Criteria c = new Criteria();
    c.setAccuracy(Criteria.ACCURACY_MEDIUM);
    c.setAltitudeRequired(false);
    c.setBearingRequired(false);
    c.setSpeedRequired(false);
    c.setCostAllowed(true);
    c.setPowerRequirement(Criteria.POWER_HIGH);
    return c;
  }
Ali
  • 12,354
  • 9
  • 54
  • 83
1

Use NETWORK_PROVIDER to get location because many times GPS will give null latitude and longitude

   m_locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0,0, this);
    m_location = m_locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

Add below permissions in manifest

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />