Reputation: 318
I'm using FusedLocationClient and broadcast receiver to get location in background, i enabled background location background permission and locations (FINE and COARSE) permission. i receive location update when app in foreground but when moving app in background i don't receive any update.
AndroidManifest.xml
<receiver
android:name=".LocationUpdatesBroadcastReceiver"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="com.test.gpstracking.LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES" />
</intent-filter>
</receiver>
LocationManager Class
class MyLocationManager private constructor(private val context: Context) {
// The Fused Location Provider provides access to location APIs.
private val fusedLocationClient: FusedLocationProviderClient =
LocationServices.getFusedLocationProviderClient(context)
private val TAG = "MyLocationManager"
// Stores parameters for requests to the FusedLocationProviderApi.
private val locationRequest: LocationRequest = LocationRequest().apply {
interval = TimeUnit.SECONDS.toMillis(4)
fastestInterval = TimeUnit.SECONDS.toMillis(4)
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}
/**
* Creates default PendingIntent for location changes.
*
* Note: We use a BroadcastReceiver because on API level 26 and above (Oreo+), Android places
* limits on Services.
*/
private val locationUpdatePendingIntent: PendingIntent by lazy {
var intent = Intent(context, LocationUpdatesBroadcastReceiver::class.java)
intent.action = LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES
PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)
}
@Throws(SecurityException::class)
@MainThread
fun startLocationUpdates() {
Log.d(TAG, "startLocationUpdates()")
if (!context.hasPermission(Manifest.permission.ACCESS_FINE_LOCATION)) return
try {
Log.e(TAG, "receiving location updates")
// If the PendingIntent is the same as the last request (which it always is), this
// request will replace any requestLocationUpdates() called before.
fusedLocationClient.requestLocationUpdates(locationRequest, locationUpdatePendingIntent)
} catch (permissionRevoked: SecurityException) {
Log.e(TAG, "not receiving location updates")
// Exception only occurs if the user revokes the FINE location permission before
// requestLocationUpdates() is finished executing (very rare).
Log.d(TAG, "Location permission revoked; details: $permissionRevoked")
throw permissionRevoked
}
}
companion object {
@Volatile
private var INSTANCE: MyLocationManager? = null
fun getInstance(context: Context): MyLocationManager {
return INSTANCE ?: synchronized(this) {
INSTANCE ?: MyLocationManager(context).also { INSTANCE = it }
}
}
}
}
My broadcast receiver
class LocationUpdatesBroadcastReceiver : BroadcastReceiver() {
private val TAG = "LocationUpdatesBroadcastReceiver"
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == ACTION_PROCESS_UPDATES) {
// Checks for location availability changes.
LocationAvailability.extractLocationAvailability(intent)?.let { locationAvailability ->
if (!locationAvailability.isLocationAvailable) {
Log.d(TAG, "Location services are no longer available!")
}
}
LocationResult.extractResult(intent)?.let { locationResult ->
locationResult.lastLocation
val location = locationResult.lastLocation
if (location != null) {
Toast.makeText(context, location.toString(), Toast.LENGTH_SHORT).show()
}
}
}
}
PS : I'm following the android source code of LocationUpdatesBackgroundKotlin from google repo on github -> link
Upvotes: 1
Views: 968
Reputation: 35
Android does not allow any kind of background service after Android Oreo, Check out this link will guide you. Access Location in Background
Upvotes: -2