app/src/main/java/com/github/polypoly/app/base/game/service/LocationService.kt
package com.github.polypoly.app.base.game.service
import android.Manifest
import android.app.Service
import android.content.Intent
import android.content.pm.PackageManager
import android.location.Location
import android.os.Build
import android.os.IBinder
import android.os.Looper
import androidx.core.app.ActivityCompat
import com.github.polypoly.app.utils.Constants
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.Priority
/**
* A service that runs in the background, receives location updates and processes them
* @property fusedLocationProviderClient The fused location provider client
* @property locationCallback The location callback
*/
abstract class LocationService: Service() {
private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
private val locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
locationResult.lastLocation?.let { location ->
// Process the received location update
processLocationUpdate(location)
}
}
}
override fun onCreate() {
super.onCreate()
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
startLocationUpdates()
return START_STICKY
}
override fun onDestroy() {
super.onDestroy()
fusedLocationProviderClient.removeLocationUpdates(locationCallback)
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
/**
* Start receiving location updates
*/
private fun startLocationUpdates() {
val locationRequest = LocationRequest.Builder(Constants.LANDLORD_TAX_POLL_RATE * 1000)
.setPriority(Priority.PRIORITY_HIGH_ACCURACY)
.setMinUpdateIntervalMillis(Constants.LANDLORD_TAX_POLL_RATE * 1000)
.build()
// Check that location permissions are granted
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
return
}
// Check that background location is enabled on Android 10+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_BACKGROUND_LOCATION
) != PackageManager.PERMISSION_GRANTED) {
return
}
// Request location updates while registering the callback
fusedLocationProviderClient.requestLocationUpdates(
locationRequest,
locationCallback,
Looper.getMainLooper()
)
}
/**
* Process a location update
* @param location The new location
*/
abstract fun processLocationUpdate(location: Location)
}