My app works fine if using foreground service to get user location, however in background I just need location for each 15 minutes, also Google
requires new Policy for getting background location so, foreground service is over my expectation.
I am trying to get location from background using WorkManager
, it can run normally every (around) 15 minutes. My location is requested, however it always returns the previous address, even 1, 2... hours are passed.
Here is my code:
class LocationWorker(private val context: Context, params: WorkerParameters) :
CoroutineWorker(context, params) {
private var fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
override suspend fun doWork() = withContext(Dispatchers.IO) {
val location = getLocation()
if (location == null) {
if (runAttemptCount < MAX_ATTEMPT) { // max_attempt = 3
Result.retry()
} else {
Result.failure()
}
} else {
Log.d(TAG, "doWork success $location")
Result.success()
}
}
private suspend fun getLocation(): Location? = withTimeoutOrNull(TIMEOUT) {
suspendCancellableCoroutine<Location?> { continuation ->
val intent = PendingIntent.getBroadcast(context, REQUEST_CODE, Intent(ACTION), 0)
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, data: Intent?) {
if (data?.action != ACTION) return
val lastLocation = LocationResult.extractResult(data)?.lastLocation
Log.e(TAG, "Get lastLocation success $lastLocation")
fusedLocationClient.removeLocationUpdates(intent)
context?.unregisterReceiver(this)
continuation.resume(lastLocation)
}
}
context.registerReceiver(receiver, IntentFilter(ACTION))
val request = LocationRequest().apply { priority = LocationRequest.PRIORITY_HIGH_ACCURACY }
fusedLocationClient.requestLocationUpdates(request, intent)
continuation.invokeOnCancellation {
fusedLocationClient.removeLocationUpdates(intent)
context.unregisterReceiver(receiver)
}
}
companion object {
val TAG = LocationWorker::class.java.simpleName
const val LOCATION_WORKER_TAG = "LOCATION_WORKER_TAG"
const val MAX_ATTEMPT = 3
private const val ACTION = "my.background.location"
private const val TIMEOUT = 60_000L
private const val REQUEST_CODE = 888
}
}
Pre-condition:
- Tested device: emulator android 27 (O_MR1)
- Route Play normally
- GPS is enabled
- Allow location permission (allow all time)
Why don't the lastknown location
not updated ?
I also tried this demo https://github.com/pratikbutani/LocationTracker-WorkManager/ . However, the problem is same, lastknown location
is not updated.
from Retrieve background location using WorkManager always return same lastknown location
No comments:
Post a Comment