Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getLastKnownLocation from NETWORK_PROVIDER on phone returns null

OK, I've spent a bunch of time searching and reading, and not just this website. Most threads deal with GPS or trying to get it to work in an emulator. The documentation at developer.android.com only explains up to a point. I can't get a simple thing to work. Like most people with this issue, I just want to get the last known location from the network provider and it won't get it, even right after I use Google maps (using the network provider because GPS was turned off) and it showed me just 1/8 to 1/4 mile away. Ok, so the "provider" (cell towers / wi-fi if turned on) is getting a fix for Google maps. I try my app and can't get the last known location. I'm not even trying to show it in Maps, I'm having it print the lat and long coordinates to the screen after a button press to get the location. The documentation says nothing about the last location having to be made from the same activity. It says it will return the last known location from the specified provider. I am specifying NETWORK_PROVIDER which the documentation says is cell towers and wi-fi. (And yes, I have that covered in the manifest.)

Does anyone know how this works? I have yet to see a good explanation, even on the Google site. If you can't tell, I'm frustrated. It's obviously something I'm doing (or not), so I'm not blaming anything/anyone but myself, except for documentation that falls a little too short for my needs.

UPDATE: I am now using a location listener and getting a location, I presume the last location. It seems logical to be able to get the last location without starting location updates through a location listener, but I wasn't, and now I am with a location listener.

Now my problem is I can't get the location to change. My code doesn't do anything right now except try to get location updates through the listener, and also accept a button press to snatch the last known location. Google Maps will show me where I am, but I keep getting a location 20 miles away in my code. I have a feeling there's a chance I might actually be getting a new location, but I might have a faulty use of final / static declarations that are keeping me from storing and using that location when I need it. My manifest has internet and fine_location permissions, and the xml for the activity works fine - it just provides a button to turn on/off the live search for location, a button for manually retrieving lastknownlocation, and a textview for displaying the latitude and longitude. I have tried to strip out non-essentials to keep this from being too long.

public class RMain extends Activity {

public boolean islivesearchon;
public static double netlistentime = 0 * 60 * 1000; // minutes * 60 sec/min * 1000 for milliseconds
public static double netlistendistance = 0 * 1609.344; // miles * conversion to meters
public static double gpslistentime = 30 * 60 * 1000; // minutes * 60 sec/min * 1000 for milliseconds
public static double gpslistendistance = 0 * 1609.344; // miles * conversion to meters

private static Location currentlocation;
private LocationManager locationManager;
private LocationListener locationListener;
public static Criteria criteria;
public TextView latview;
public TextView longview;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_rmain);

    latview = (TextView) findViewById(R.id.display_latitude);
    longview = (TextView) findViewById(R.id.display_longitude);

    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    // setup bestProvider
    criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    String bestprovider = locationManager.getBestProvider(criteria, true);

    // get an initial current location
    currentlocation = locationManager.getLastKnownLocation(bestprovider);
    latview.setText(Double.toString(currentlocation.getLatitude()));
    longview.setText(Double.toString(currentlocation.getLongitude()));

    // Define locationListener interface
    locationListener = new LocListener();

    // React to LiveSearch toggle button press
    final Button livesearch = (Button) findViewById(R.id.button_livesearch);
    livesearch.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            TextView livesearchview = (TextView) findViewById(R.id.button_livesearch);
            boolean isNetEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
            boolean isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

            if(islivesearchon) {
                locationManager.removeUpdates(locationListener);
                islivesearchon = false;
                livesearchview.setText("Live Search is OFF");
            }
            else {
                // ideally should check for !isProviderEnabled first, then provide option for turning it on
                if(isNetEnabled) {
                    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, (long) netlistentime, (float) netlistendistance, locationListener);
                    islivesearchon = true;
                    livesearchview.setText("Live Search is ON");
                }
                // ideally should check for !isProviderEnabled first, then provide option for turning it on
                if(isGpsEnabled) {
                    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, (long) gpslistentime, (float) gpslistendistance, locationListener);
                    islivesearchon = true;
                    livesearchview.setText("Live Search is ON");
                }
            }
        }
    });

    // Respond to Get Location button click to get last known location
    final Button getlocation = (Button) findViewById(R.id.button_getlocation);
    getlocation.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {

            String bestprovider = locationManager.getBestProvider(criteria, true);
            Location lastlocation = locationManager.getLastKnownLocation(bestprovider);

            latview.setText(Double.toString(lastlocation.getLatitude()));
            longview.setText(Double.toString(lastlocation.getLongitude()));
        }
    });

}

private class LocListener implements LocationListener {

    @Override
    public void onLocationChanged(Location latestlocation) {
      // Called when a new location is found by the network location provider.
        currentlocation.set(latestlocation);
        latview.setText(Double.toString(currentlocation.getLatitude()));
        longview.setText(Double.toString(currentlocation.getLongitude()));
    }

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

    @Override
    public void onProviderEnabled(String provider) {}

    @Override
    public void onProviderDisabled(String provider) {}
};

}

like image 690
crispy Avatar asked Dec 11 '12 06:12

crispy


2 Answers

Try to check with this... once your onLocationChange is called, after that the old values you can get using last known location.

 locationManager = (LocationManager)this.getSystemService(LOCATION_SERVICE);

        location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        if (location != null) {

            old_latitude=location.getLatitude();
            old_longitude=location.getLongitude();
            Log.d("old","lat :  "+old_latitude);
            Log.d("old","long :  "+old_longitude);

            this.onLocationChanged(location);
        }   
like image 169
Rahul Avatar answered May 20 '23 21:05

Rahul


It returns 'null', when the Service is disabled in Settings > Location and Security > location through network

So that can happen quite often.

like image 25
Nirav Ranpara Avatar answered May 20 '23 23:05

Nirav Ranpara