LocationManager.NETWORK_PROVIDER need network, but it is real, not precise. if you want to use LocationManager.GPS_PROVIDER, the situation must be outdoor instead of indoor, because GPS location need satellite, if you are in any building, the satellite cannot find you! pleasle go outdoor and check with GPS_PROVIDER again!

*best approach is getting location from both of GPS and NETWORK and check any of then that was not null and more accurate useing it.

Answer from Mohammad Reisi on Stack Overflow
Top answer
1 of 3
13

The primary reason why you aren't getting updated location information quickly is that you're relying on the NETWORK_PROVIDER in the RestaurantHelper.getLastKnownLocation() method, but registering a LocationListener for the GPS_PROVIDER in onCreate().

So, this code in RestaurantHelper.getLastKnownLocation():

Location location = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

...should be changed to:

Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);

In theory, this should then give you the latest GPS location, which should have been refreshed when you register the listener. Conversely, you could also change to listening to the NETWORK_PROVIDER in onCreate() and leave RestaurantHelper.getLastKnownLocation() as is. It depends on your accuracy requirement - if you want high accuracy locations to return the nearest location to the nearest building level (e.g., 5-30m), you should use the GPS_PROVIDER. But, if you can live with coarser accuracy, the NETWORK_PROVIDER typically returns a new location much faster than GPS, especially if you're indoors, and sometimes this can be fairly accurate if derived from WiFi.

Another approach would be to listen to both GPS_PROVIDER and NETWORK_PROVIDER by registering both via two requestLocationUpdates() lines in onCreate(), and then checking to see most recent timestamp on the Location from lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); and lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);, and using the one that was updated more recently.

I would also recommend the following changes to make your code reliable on a large number of Android devices:

  1. Specify the requestLocationUpdates() minDistance parameter as 0 when listening for GPS or NETWORK location updates - the minDistance parameter has a history of being unreliable and unpredictable in the way its interpreted by OEMs, until Android 4.1.
  2. Switch to the new Fused Location Provider - this should be much more reliable when calling the getLastKnownLocation() method than the Android framework location APIs, and more consistent across different devices. Note that this relies on Google Play Services SDK, which is only available on Android 2.2 and higher.
2 of 3
5

I have 2 advice for you

  1. LocationClient video, is the new way of doing location stuff. It has improvements over the LocationManager that can be a pain to manage and develop.

  2. If you need to use LocationManager, you must know that requestLocationUpdates is buggy (very buggy). Since all its implementations on custom hardware differ. There is a hack/workaround that works. Before you call requestLocationUpdates, just kick start it with the following

Code :

 HomeScreen.getLocationManager().requestLocationUpdates(
    LocationManager.NETWORK_PROVIDER, 0, 0, new LocationListener() {
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
        }
        @Override
        public void onProviderEnabled(String provider) {
        }
        @Override
        public void onProviderDisabled(String provider) {
        }
        @Override
        public void onLocationChanged(final Location location) {
        }
    });
🌐
Tabnine
tabnine.com › home › code library
LocationManager.requestLocationUpdates - Java
July 25, 2024 - Get the answers and suggestions you need from our AI code assistant. Get started in minutes with a free 90 day trial of Tabnine Pro.
🌐
Stack Overflow
stackoverflow.com › questions › 25735978 › locationmanager-requestlocationupdates-not-responding
android - LocationManager.requestLocationUpdates not responding - Stack Overflow
might it be a problem because i call an intent service from another instance of intent service? although the intent service works fine ... Just making sure - is GPS turned on? do you get location updates from GPS on another app (e.g. Google Maps)? If not, that might not be an issue with your code but a device setting (or location since GPS won't work inside buildings...)
🌐
Stack Overflow
stackoverflow.com › questions › 71582020 › requestlocationupdates-is-not-working-on-android-11-12
locationmanager - requestLocationUpdates is not working on Android 11 & 12 - Stack Overflow
This code worked well for Android 9 and 10, but it is not working for 11 and 12. The initial location is updated but the following location is not updated at all. FINE and COARSE location permissions are requested. What could be the problem? if (!isGPSEnabled && !isNetworkEnabled) { lat = 0; lon = 0; } else { this.isGetLocation = true; // GPS if (isGPSEnabled) { locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, this); if (locationManager != null) { location = locationManager .getLastKnownLocation(LocationManager.GPS_PROVIDER); if(location != null && location.getTime()
Find elsewhere
🌐
Stack Overflow
stackoverflow.com › questions › 71822017 › locationmanager-requestlocatoinupdates-is-not-working-on-android-11-and-12
LocationManager.requestLocatoinUpdates() is not working on android 11 and 12 - Stack Overflow
try { locationManager = (LocationManager) mContext .getSystemService(LOCATION_SERVICE); // get GPS information isGPSEnabled = locationManager .isProviderEnabled(LocationManager.GPS_PROVIDER); // get Network information isNetworkEnabled = locationManager .isProviderEnabled(LocationManager.NETWORK_PROVIDER); // Log.i(TAG, "GPS enabled: " + isGPSEnabled + " network enabled: " + isNetworkEnabled); if (!isGPSEnabled && !isNetworkEnabled) { lat = 0; lon = 0; } else { this.isGetLocation = true; // GPS if (isGPSEnabled) { locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, this
🌐
DaniWeb
daniweb.com › programming › mobile-development › threads › 516044 › requestlocationupdates-does-not-work
android-development - requestLocationUpdates does not work [SOLVED] | DaniWeb
April 27, 2018 - package com.example.hp430.gpslocaction; import android.Manifest; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.provider.Settings; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.Text
Top answer
1 of 1
1

Workaround for this issue is to use only one LocationManager and one LocationListener. If your app has needs for different kind of simultaneous location requests (with different parameters), then you need to implement a "location request handler" which decides which parameters should be used for the location request i.e. which parameters have the tightest requirements for location.

Here is a simple example code that explains the idea of "location request handler":

Copyclass LR {

    long lock_min_time; // defined in set_lock_lr before using
    float lock_min_dist;
    boolean lock_active = false;

    long idle_min_time = 3600000; // 1 per hour
    float idle_min_dist = 200;
    boolean idle_active = true;

    long fast_min_time = 0;
    float fast_min_dist = 0;
    boolean fast_active = false;

    //constructor
    public LR()
    {}

    public void set_lock_lr(long min_time, float min_dist, boolean active)
    {
        lock_active = active;
        lock_min_dist = min_dist;
        lock_min_time = min_time;
        System.out.println("LR lock set: "+min_time+", "+min_dist+", "+active);
        update_location_request();
    }

    public void set_idle_lr(boolean active)
    {
        idle_active = active;
        System.out.println("LR idle set: "+active);
        update_location_request();
    }

    public void set_fast_lr(boolean active)
    {
        fast_active = active;
        System.out.println("LR fast set: "+active);
        update_location_request();
    }

    private void update_location_request()
    {
        // Remove current location request
        mlocManager_basic.removeUpdates(mlocListener_basic);

        if(fast_active)
        {
            mlocManager_basic.requestLocationUpdates(LocationManager.GPS_PROVIDER, fast_min_time, fast_min_dist, mlocListener_basic);
            System.out.println("LR: fast_active");
        }
        else if(lock_active)
        {
            mlocManager_basic.requestLocationUpdates(LocationManager.GPS_PROVIDER, lock_min_time, lock_min_dist, mlocListener_basic);
            System.out.println("LR: lock_active");
        }
        else if(idle_active) // only idle updates
        {
            mlocManager_basic.requestLocationUpdates(LocationManager.GPS_PROVIDER, idle_min_time, idle_min_dist, mlocListener_basic);
            System.out.println("LR: idle_active");
        }
    }
}
🌐
Stack Overflow
stackoverflow.com › questions › 54287419 › can-not-call-requestlocationupdates-with-given-arguments
android - Can not call requestLocationUpdates with given arguments - Stack Overflow
An IllegalArgumentException will throw if provider is null or doesn't exist on this device. I think the "dsa" provider may not exist in your device. You should use LocationManager.NETWORK_PROVIDER, LocationManager.PASSIVE_PROVIDER, or LocationManager.GPS_PROVIDER
🌐
Microsoft Learn
learn.microsoft.com › en-us › dotnet › api › android.locations.locationmanager.requestlocationupdates
LocationManager.RequestLocationUpdates Method (Android.Locations) | Microsoft Learn
Note: Since Android KitKat, Criteria requests will always result in using the #FUSED_PROVIDER. See #requestLocationUpdates(String, LocationRequest, Executor, LocationListener) for more detail on how this method works. This member is deprecated. Use #requestLocationUpdates(String, long, float, LocationListener, Looper) instead to explicitly select a provider. Java documentation for android.location.LocationManager.requestLocationUpdates(long, float, android.location.Criteria, android.location.LocationListener, android.os.Looper).
🌐
Narkive
android-developers.narkive.com › WDx9j58w › onlocationchanged-not-working-as-expected
onLocationChanged not working as expected
New Location: " + location.toString()); notifyLocationChange(location); } public void onProviderDisabled(String provider) { Log.i(TAG, "Provider disabled: " + provider); } public void onProviderEnabled(String provider) { Log.i(TAG, "Provider enabled: " + provider); locationManager.requestLocationUpdates(provider, this.minDistance, this.minTime, this); } public void onStatusChanged(String provider, int status, Bundle extras) { Log.i(TAG, "Provider status: " + provider + "=" + status); } } To test I'm setting minTime=60000 and minDistance=50, which AFAIK should notify every 1 minute if the location has changed more than 50 mts, right?.
🌐
Stack Overflow
stackoverflow.com › questions › 13442991 › locationmanager-requestlocationupdates
android - LocationManager requestLocationUpdates - Stack Overflow
Handler handler; // this Handler is initialized in the following thread Runnable r = new Runnable() { public void run() { Looper.prepare(); handler = new Handler() { @Override public void handleMessage(Message msg) { Log.d("MSG", msg.toString()); } }; Looper.loop(); } }; Thread t = new Thread(r); t.start(); LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE); lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, new LocationListener() { public void onLocationChanged(Location location) { Log.d("UPD", "onLocationChanged"); } [...] }, handler.getLooper());
Top answer
1 of 2
40

You are implementing LocationListener in your activity MainActivity. The call for concurrent location updates will therefor be like this:

mLocationClient.requestLocationUpdates(mLocationRequest, this);

Be sure that the LocationListener you're implementing is from the google api, that is import this:

import com.google.android.gms.location.LocationListener;

and not this:

import android.location.LocationListener;

and it should work just fine.

It's also important that the LocationClient really is connected before you do this. I suggest you don't call it in the onCreate or onStart methods, but in onResume. It is all explained quite well in the tutorial for Google Location Api: https://developer.android.com/training/location/index.html

2 of 2
13

I use this one:

LocationManager.requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)

For example, using a 1s interval:

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000,0,this);

the time is in milliseconds, the distance is in meters.

This automatically calls:

public void onLocationChanged(Location location) {
    //Code here, location.getAccuracy(), location.getLongitude() etc...
}

I also had these included in the script but didnt actually use them:

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

In short:

public class GPSClass implements LocationListener {

    public void onLocationChanged(Location location) {
        // Called when a new location is found by the network location provider.
        Log.i("Message: ","Location changed, " + location.getAccuracy() + " , " + location.getLatitude()+ "," + location.getLongitude());
    }

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000,0,this);
    }
}