5

I've been working on an app that tracks the user's position. For this I have used the google play services location module (a.k.a. fused location). All in all everything works fine.

BUT sometimes, completely random, I no longer receive location updates from the google location services, at all! I mean, my app is working fine, but no location updates. Not only that,if I start up google maps it can't get a fix on my location (even with GPS turned on). Reinstalling my app doesn't fix the issue. Out of the 3 taxi apps that I have on my phone, 2 of them can pinpoint my location. (Most likely they are using the old LocationManager to get the device's location).

I found that to fix this issue I have but to restart my device. But this is very unsettling, I can't expect my users to restart their devices whenever something goes wrong with the location updates. (though this has only happened to me about 6 times in the past 2 months)

So: Does anyone know about this issue and is there a work-around for it? Is my app somehow crashing google play services?

Sebek
  • 642
  • 8
  • 22
  • any solution to this yet? – Abhinav Upadhyay Jan 26 '18 at 13:34
  • @AbhinavUpadhyay I eventually switched to using the old `LocationManager`. It's not as smart or responsive but I don't have any issues with it stopping for no reason. – Sebek Jan 30 '18 at 10:10
  • 1
    I am having same issue right now , my temporary solution is this : I asked the drivers to let the app be open before they turn screen off which means the app is always open when they are at their working time. I guess the Android OS doesn't let the app to use GPS when it is in the background because of battery usage maybe. but this solution is not good it doesn't satisfy my customers very well. definitely looking for better solution . all the best sebek – iDeveloper May 08 '18 at 04:09
  • OMG it's 5 years now and I still get this error. It's like after a specific period of time, Google starts reset google location service on ALL devices and everything is cleaned. ALL I mean a lot of my users complain about gps issue at the same time . The only way to fix to fix this I know is open Google Map and turn back to the app. Any update on this issue please help – Tam Huynh Jun 11 '19 at 15:19

4 Answers4

1

I have found that if you don't unsubscribe from the LocationManager by calling removeUpdates on app close, it will sometimes cause the issue you are experiencing.

Nyx
  • 2,233
  • 1
  • 12
  • 25
  • Thanks for your input. I do use `locationClient.removeLocationUpdates(locationPendingIntent);` But another problem came up just now. I restarted my phone several times and I still can't get google maps to pinpoint my location. I turned gps on off, still nothing. – Sebek Apr 30 '14 at 08:27
  • Are you sure it's getting called every time? In my situation there was a weird case where it wasn't getting called! – Nyx May 05 '14 at 15:53
1

I have recently experienced the same problem, Sebek. I do not believe the answer NYX gave is the correct one. There seems to be some other fix for the problem that only Google knows. Why do I say this?

I have created an app that uses Fused Location Services to get the location of the mobile device at 30 second intervals and toast the position when the app is in focus. But for some reason the Fused Services just stopped working. I tried again and again and again...switched on all location services - WIFI, GPS and Network...nothing worked. The Fused Location services remained off.

But then I tried something...I started up my app and then using the inbuilt Android Task Manager I launched Google Maps...and BOOM! The Fused Location Services on my app worked and started reporting location data on the 30-second mark everytime...and for some weird reason the accuracy of the locations was also improved...up to 5 metre accuracy!! I tried the same procedure over and over - first launch my app and nothing...then launch Maps and BOOM! - it worked everytime. A 100% success when I launched Google Maps.

So this is clear proof that Google is running some code that ensures the Fused Location Service doesn't drop out when Google apps are launched and needs the location service. Sebek, maybe you can try this and see if you get the same results. Maybe then we can progress somewhere in finding a true fix.

Cheers, Shore-T ...

SilSur
  • 495
  • 1
  • 6
  • 21
  • So it's been a few months since I asked this question, and I'm having trouble remembering how I handled the whole thing (also the tracking feature for my app is only partly in use). I have a service from where I start the whole fused location services but I DO NOT use `onLocationChangedListener`. Instead I request the location updates through a pending Intent to an IntentService. `locationClient.requestLocationUpdates(locationRequest, locationPendingIntent);` In the new class `public class LocationIntentService extends IntentService` I catch the intent `onHandleIntent` and get the location. – Sebek Jul 29 '14 at 11:27
  • `Bundle b = intent.getExtras(); Location location = (Location) b.get(LocationClient.KEY_LOCATION_CHANGED);` – Sebek Jul 29 '14 at 11:29
1

Try change location mode to "GPS only" and than turn back to "Hight Accuracy". The problem occurs sometimes when you are indoor and this fix it.

See here how to switch GPS programatically on/off

Pavel Aslanov
  • 180
  • 2
  • 6
  • 1
    I don't think this answer is valid, as it would be sort of ridiculous to tell your app users to restart their location services just to switch it back, when other apps don't have that issue. – GrumpyCrouton Jun 14 '17 at 19:47
  • If that link makes your answer more solid, it should be included in your answer, and not in a comment. – GrumpyCrouton Jun 14 '17 at 20:28
0

I have been struggling with this problem for several weeks , I believe the android OS restrict an app which is in the background this means the app cant access to gps after one or two hours when it is in the background . may be because of less battery usage .

the solution I am using is this :

this is BaseActivity which is used for every activity :

 public abstract class BaseActivity extends AppCompatActivity {
 @Override
 protected void onPause() {
     super.onPause();
       MyApplication.activityPaused();
 }
 @Override
 protected void onResume() {
     MyApplication.activityResumed();
     super.onResume();
 }
}

here is MyApplication class :

public class MyApplication extends Application  {

public static boolean isActivityVisible() {
    return activityVisible;
}

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

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();
            }
        }
    }
}

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.

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

I hope I could explain my solution properly . All the best ...

iDeveloper
  • 1,699
  • 22
  • 47
  • Thank you for taking the time to write this. However I eventually turned back to using `LocationManager`, which isn't as smart as fused location but it is more reliable. – Sebek May 09 '18 at 11:40
  • Welcome . with this locationManger solution isYour problem solved? I mean does app get location even when device is lock or screen off? – iDeveloper May 09 '18 at 12:48
  • Yes. It solves the problem, and it works on devices that don't have google play services installed(e.g. Chinese devices), unlike fused location. However, it does have it's drawbacks: reduced accuracy, and the `LocationManager` is tied to your app, so it will start only when the user launches your app (so it may take a few seconds or a minute to get the first location), and stops if the user shuts down your service, you will lose your last known location. But then again I haven't researched fused location in a while, maybe things have changed for the better. – Sebek May 09 '18 at 13:09
  • this is very annoying for driver , I have been using this solution but they were so unsatisfied. stop/start location update every 30 sec my be the solution but it increase unnormal location when user stays in one plays . – iDeveloper Oct 24 '18 at 08:20