androidbackgroundlocationlocation-providerfusedlocationproviderapi

Getting too frequent location updates in the background


In my app I am using ReactiveLocationProvider to get background location updates. (library link) When my app is minimised (enters onPause) it starts receiving updates. It works fine, but the problem is I don't want that frequent updates. For example, in my code I have a LocationRequest that is supposed to get location update (one) when the user moves 1km and at least 10 minutes (setFastestInterval) have passed. According to my log, I am receiving more updates than needed. Anyone knows why?

this is my code in my MainActivity on create method:

public class MainActivity extends AppCompatActivity {
LocationRequest request;
ReactiveLocationProvider locationProvider;
Subscription subscription;
Subscription onlyFirstTimeSubscription;
NotAbleToGetWeatherDataTask mNotAbleToGetWeatherDataTask = new NotAbleToGetWeatherDataTask();
int numOfBackgroundUpdates = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //-----------MY CODE STARTS HERE-----------------
    request = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)
            .setSmallestDisplacement(1000)
            .setFastestInterval(10 * 1000)
            .setInterval(30 * 60 * 1000);
    locationProvider = new ReactiveLocationProvider(this);
}

and my onPause method:

@Override
protected void onPause() {
    super.onPause();
    //subscribe for background location updates...
    subscription = locationProvider.getUpdatedLocation(request)
            .subscribe(new Action1<Location>() {
                @Override
                public void call(Location location) {
                    Log.d(TAG, "Getting Background updates...");
                    MainActivity.this.latitude = location.getLatitude();
                    MainActivity.this.longitude = location.getLongitude();
                    numOfBackgroundUpdates++;

                }
            });
}

and I am unsubscribing from the request on destroy:

   @Override
protected void onDestroy() {
    Log.d(TAG, "OnDestroy Called!");
    subscription.unsubscribe();
    super.onDestroy();
}

recent log (I have moved 1km and at least 10minutes have passed)

12-28 17:12:25.564 29845-29845/? D/MainActivity: Getting Background  updates...
12-28 17:16:06.918 29845-29845/? D/MainActivity: Getting Background updates...
12-28 17:16:06.924 29845-29845/? D/MainActivity: Getting Background updates...
12-28 17:16:06.925 29845-29845/? D/MainActivity: Getting Background updates...
12-28 17:16:06.927 29845-29845/? D/MainActivity: Getting Background updates...
12-28 17:16:06.928 29845-29845/? D/MainActivity: Getting Background updates...
12-28 17:16:06.930 29845-29845/? D/MainActivity: Getting Background updates...
12-28 17:16:06.931 29845-29845/? D/MainActivity: Getting Background updates...
12-28 17:16:06.940 29845-29845/? D/MainActivity: Getting Background updates...
12-28 17:16:06.942 29845-29845/? D/MainActivity: Getting Background updates...
12-28 17:16:06.942 29845-29845/? D/MainActivity: Getting Background updates...
12-28 17:16:06.946 29845-29845/? D/MainActivity: Getting Background updates...
12-28 17:16:06.949 29845-29845/? D/MainActivity: Getting Background updates...
12-28 17:16:06.951 29845-29845/? D/MainActivity: Getting Background updates...
12-28 17:16:06.951 29845-29845/? D/MainActivity: Getting Background updates...
12-28 17:16:06.951 29845-29845/? D/MainActivity: Getting Background updates...
12-28 17:16:40.371 29845-29845/? D/MainActivity: Getting Background updates...

Solution

  • Firstly adjust this:
    Your setFastestInterval in ms is 10 * 1000 --> For 10 minutes you need to make this: 60 * 10 * 1000

    Then have a look at this:
    You need to create one instance of your location provider class for the duration of your app:

    If you look at these links to the ReaciveLocationProvider You'll see passing the current context as a parameter.

    ReactiveLocationProvider locationProvider = new ReactiveLocationProvider(context);
    locationProvider.getLastKnownLocation()
    .subscribe(new Action1<Location>() {
        @Override
        public void call(Location location) {
            doSthImportantWithObtainedLocation(location);
        }
    });
    
    reactiveLocationProvider = new ReactiveLocationProvider(this);
    

    The author is passing the context as a parameter. I suggest you go through all your instances of the reactiveLocationProvider and create a single instance.

    So create a static final context, using getapplicationcontext, or a similar method as suggested below.

    example: (this is taken from my library

    LocationManager locationManager = (LocationManager) getSystemService(_CONTEXT);
    

    Example in my custom class I pass a final context:

    public class LocFinder extends Service implements LocationListener {
        private final Context mContext;
    
        public LocFinder(Context context) {
            this.mContext = context;
        }
    

    Without examining the github code more thoroughly it's hard to say whether the author has safe guarded against this, but if you are calling it from MainActivity in oncreate like that, then you could be creating a new request.

      request = LocationRequest.create()
    

    You are also asking for the location on OnPause:

    MainActivity.this.latitude = location.getLatitude();
    MainActivity.this.longitude = location.getLongitude();
    

    I'm not 100% clear on the need for doing this.

    Also make note of the original author's use of final when creating a locationrequest. Which supports the idea of controlling your request calls for the lifetime of the app.

    Shout out if you need more help.