brandonhilkert
brandonhilkert

Reputation: 4475

Keep GPS Location Alive w/ Device Owner App

We have a device owner app installed on a Samsung A13. The device is relatively low powered. The app has the necessary permissions and we've programmatically disabled battery optimizations for the device owner app.

The intention is to have the GPS track location every 5 min. when still, and every 5 sec. when moving (e.g. walking, running, biking, in a car, etc.). To do this, we've hooked into Activity Recognition, which works well.

Our issue is when the device goes into Idle mode, the updates stop at the expected intervals. We've tried the following without success:

  1. From a foreground service, subscribe to updates in the FusedLocationProviderClient and do something like:
            LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, IntervalManager.FIVE_SECONDS)
                .setIntervalMillis(interval)
                .setMinUpdateIntervalMillis(interval)
                .setMaxUpdateDelayMillis(interval)
                .build()
  1. From the Foreground service, written a class w/ coroutines to get the current location at every interval:
        locationUpdateJob = scope.launch {
            while(isActive) {
                var location = getCurrentLocation()

                if (location != null) {
                    broadcastLocation(location)
                }
                delay(context.config.locationUpdateInterval)
            }
        }

From detailed logs of this approach, it appears that when the device enters IDLE mode (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED), the calls to getCurrentLocation just hang. Once the device comes out of idle mode by unlocking the screen, they'll continue work again. I've confirmed the foreground service is alive and working well.

  1. Use a wake lock around the call to getCurrentLocation
    suspend fun getCurrentLocation(): Location? {
        val wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG)
        wakeLock.acquire()
        // Code to get current location
        wakeLock.release()

That doesn't seem to do enough to get the location data to fire.

We recognize there's a trade-off w/ battery life and willing to take that trade-off so as long as the location data is consistently transmitted.

The app itself is side-loaded, so Google Play reviews should not be a factor in the approach.

What do we need to do make this more reliable when the phone enters IDLE mode?

Upvotes: 0

Views: 105

Answers (0)

Related Questions