I am trying to get the current location of the device in foreground service using the Fused Location Provider Client in Android O. But the service is killed right after location request is made. I am thinking the service is killed because the fused location provider client gets the location in another background thread and when looking at the perspective of the service, it's task is done. The issue is after service is destroyed no location update is received. How can I keep the service alive until service is specifically stopped?
My Service Class :
private val TAG = LocationService::class.java.simpleName
companion object {
val STOP_ACTION = "STOP_ACTION"
}
private lateinit var mFusedLocationClient: FusedLocationProviderClient
private lateinit var mLocationCallback: LocationCallback
private lateinit var notificationManager: NotificationManager
private val notificationId = 1
private val UPDATE_INTERVAL_IN_MILLISECONDS = 5000L
private val FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = 500L
private val CHANNEL_ID = TAG
override fun onHandleIntent(intent: Intent?) {
Log.d(TAG, "onHandleIntent start")
if (intent?.action.equals(STOP_ACTION)) {
Log.d(TAG, "stop service")
stopForeground(true)
stopSelf()
} else {
Log.d(TAG, "start location update")
createNotificationChannel()
val notificationIntent = Intent(this, OnboardingActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
this,
0, notificationIntent, 0
)
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Tracking realtime location")
.setContentText("Tap to open the application")
.setSmallIcon(R.drawable.logo)
.setContentIntent(pendingIntent)
.setOngoing(true)
.build()
startForeground(notificationId , notification)
startLocationUpdates()
}
}
override fun onCreate() {
super.onCreate()
notificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
mLocationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
locationResult ?: return
for (location in locationResult.locations) {
Log.d(TAG, "$location")
}
}
override fun onLocationAvailability(p0: LocationAvailability?) {
super.onLocationAvailability(p0)
}
}
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.e(TAG, "onStartCommand")
super.onStartCommand(intent, flags, startId)
return START_STICKY
}
override fun onDestroy() {
super.onDestroy()
mFusedLocationClient.removeLocationUpdates(mLocationCallback)
Log.e(TAG, "location service destroyed")
}
private fun startLocationUpdates() {
val mLocationRequest = LocationRequest()
mLocationRequest.interval = UPDATE_INTERVAL_IN_MILLISECONDS
mLocationRequest.fastestInterval = FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS
mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
try {
mFusedLocationClient.requestLocationUpdates(
mLocationRequest,
mLocationCallback,
Looper.myLooper()
)
} catch (e: SecurityException) {
Log.e(TAG, "Lost location permission. Could not request updates. $e")
}
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val nChannel = notificationManager.getNotificationChannel(CHANNEL_ID)
if (nChannel == null) {
val serviceChannel = NotificationChannel(
CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
)
notificationManager.createNotificationChannel(serviceChannel)
}
}
}
}
Any help is highly appreciated.