Nininea
Nininea

Reputation: 2729

Fused location stops sending updates after several hours

If I left application turned on for several hours fused location stops sending updates...

I am creating location request with hight priority , here is code :

LocationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setExpirationDuration(TimeUnit.SECONDS.toMillis(LOCATION_TIMEOUT_IN_SECONDS))
                .setInterval(LOCATION_UPDATE_INTERVAL);

Here is client and callback :

LocationCallback mLocationCallback = new LocationCallback() {
        @Override
        public void onLocationAvailability(LocationAvailability locationAvailability) {
            super.onLocationAvailability(locationAvailability);
        }

        @Override
        public void onLocationResult(LocationResult locationResult) {
            super.onLocationResult(locationResult);
            //Update location
        }
    };
    mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
    mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest, mLocationCallback, null);

LOCATION_TIMEOUT_IN_SECONDS is 5 second, but updates is not always running, I stop and start it manually, when my application needs location. Like it is documented .

Everything works fine if application is running one or two hours, but if I left it open for a long time, it stops working....

I requested location updates from Activity on button click, after 10 seconds, I stop location updates manually... If I left it whole night , this means that Activity is alive whole night... after this, when I request location updates again, it is not coming...

Any solution or idea?

Upvotes: 4

Views: 1537

Answers (2)

iDeveloper
iDeveloper

Reputation: 1725

here is MyApplication class :

public class MyApplication extends Application  {

  public static boolean isActivityVisible() {
   return activityVisible;
 }

 public static void setVisibilityTrue() {
  activityVisible = true;
 }

this is my baseActivity Class :

 public static void activityResumed() {
 boolean isScreenOn = true;
 // isScreenOn() method is deprecated API level 21. You should use 
 isInteractive instead:
 PowerManager pm = (PowerManager) 
 MyApplication.getInstance().getSystemService(Context.POWER_SERVICE);
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
     isScreenOn = pm.isInteractive();
 } else {
    isScreenOn = pm.isScreenOn();
 }
 if (isScreenOn) {
    activityVisible = true;
 }

}

 public static void activityPaused() {
 boolean isScreenOn = true;
 PowerManager pm = (PowerManager) 
MyApplication.getInstance().getSystemService(Context.POWER_SERVICE);
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
     isScreenOn = pm.isInteractive();
 } else {
     isScreenOn = pm.isScreenOn();
 }
 if (isScreenOn) {
     activityVisible = false;
 }

}
private static boolean activityVisible;

}

when app is in the background we bring it to foreground , with a timer every 30 seconds we check if app screen is locked or not if it is locked we open the app : private void bringApplicationToFront(Context context) { /** * check if motitor screen is Off/On * */ boolean isScreenOn = true; PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { isScreenOn = pm.isInteractive(); } else { isScreenOn = pm.isScreenOn(); } if (!isScreenOn) { /** * check if app is fore/back ground * */ boolean isInForeBackground = false; try { isInForeBackground = MyApplication.isActivityVisible(); } catch (Exception e) { e.printStackTrace(); } if (!isInForeBackground) { Intent notificationIntent = new Intent(context, ActivitySplash.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); try { pendingIntent.send(); } catch (PendingIntent.CanceledException e) { e.printStackTrace(); } } } }

I think if the app comes to foreground its priority is high then it can use gps all the time .

the tricky part is when app is in the background and screen is locked the onPause() is called after reopening the app (bring it to foreground) means activityVisible is set to false (means not visible which is not true), actually it is correct but it is not what I wanted , to solve this problem I never let the activityVisible to be set when screen is locked and when app is reopened in splash I set the activityVisible to true.

hope it could help ...

Upvotes: 0

pepela
pepela

Reputation: 423

setExpirationDuration(long millis)

from docs:

Set the duration of this request, in milliseconds.

The duration begins immediately (and not when the request is passed to the location client), so call this method again if the request is re-used at a later time.

The location client will automatically stop updates after the request expires.

The duration includes suspend time. Values less than 0 are allowed, but indicate that the request has already expired.

If you want to receive location updates forever, remove it or set appropriate time.

Upvotes: 2

Related Questions