Android Location Service
Get Location on background
In Android, we can get location data on background.
Background means that the user make the app background.(If app is clear, we cannot get)
Service + Google SDK
In this time, we use Google
(Google Play SDK wraps Android location and we don’t care the Internet connection and GPS at the same time)
To use Google Play SDK, you need to add following to build.gradle
compile 'com.google.android.gms:play-services-location:11.4.2'
LocationBackgroundService
class LocationBackgroundService : Service() {
private val TAG : String = "LocationService"
private lateinit var fusedLocationClient: FusedLocationProviderClient
private lateinit var localCallback: LocationCallback
override fun onBind(intent: Intent?): IBinder? {
return null
}
override fun onCreate() {
super.onCreate()
Log.d(TAG, "Start Service")
if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
// Check Permission work for background?
checkPermission()
} else {
// Go
startLocationUpdates()
}
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
super.onDestroy()
// Remove all location listeners
stopLocationUpdates()
}
/**
* Helpers
*/
private fun startLocationUpdates() {
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
if (fusedLocationClient != null) {
try {
fusedLocationClient.requestLocationUpdates(createLocationRequest(), object : LocationCallback() {
override fun onLocationAvailability(locationAvailability: LocationAvailability) {
Log.d(TAG, "Location Available")
}
override fun onLocationResult(result: LocationResult) {
for (location: Location in result.locations) {
Log.d(TAG, "Latitude : " + location.latitude)
Log.d(TAG, "Longitude : " + location.longitude)
val message: String = String.format("Latitude %f, Longitude %f", location.latitude, location.longitude)
Toast.makeText(applicationContext, message, Toast.LENGTH_SHORT).show()
}
}
}, null)
} catch (e: SecurityException) {
// Suppress
}
}
}
private fun checkPermission() {
if (locationpermission()) {
startLocationUpdates()
}
}
private fun locationpermission(): Boolean {
// For Emulator
return ContextCompat.checkSelfPermission(applicationContext, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(applicationContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
private fun createLocationRequest(): LocationRequest {
val locationRequest: LocationRequest = LocationRequest()
locationRequest.interval = 10000 // Interval
locationRequest.fastestInterval = 5000
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
return locationRequest
}
private fun stopLocationUpdates() {
if (fusedLocationClient != null) {
fusedLocationClient.removeLocationUpdates(localCallback)
}
}
}
Unfortunately, we cannot show Permission UI from Service. If we need to show before starting service, we have call Permission dialog API on Activity.
Start Service
To use this service, we need 2
- Register service in AndroidManifest.xml
- Call startServcice from any Activity
Call Start Service
startService(Intent(this, LocationBackgroundService::class.java))
Result
This works even if the app becomes background.
Toast is shown every 10 seconds or so.
