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.