'How to get location in Android 12 and above when app is closed?
I am trying to get location in android 12 when app is closed using WorkManager. But the issue is, it work for few minutes and get killed by the OS. I am unable to find out why this is happening.
What could be the solution for this?
Question updated with code
WorkManager
class LocationWorker(
private val context: Context,
private val workerParameters: WorkerParameters
) : CoroutineWorker(context, workerParameters) {
private val NOTIFICATION_ID = 10
private var mRandomNumber = 0
private var mIsRandomGeneratorOn = false
private val MIN = 0
private val MAX = 100
private lateinit var fusedLocationClient: FusedLocationProviderClient
override suspend fun doWork(): Result {
fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
setForeground(createForeGroundInfo())
getLocation()
return Result.success()
}
private fun createForeGroundInfo(): ForegroundInfo {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createChannel()
}
val notification =
NotificationCompat.Builder(applicationContext, NOTIFICATION_ID.toString())
.setContentTitle("Location Sharing")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setSmallIcon(R.drawable.ic_location)
.setOngoing(true)
.build()
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ForegroundInfo(NOTIFICATION_ID, notification, FOREGROUND_SERVICE_TYPE_LOCATION)
} else {
ForegroundInfo(NOTIFICATION_ID, notification)
}
}
@RequiresApi(Build.VERSION_CODES.O)
private fun createChannel() {
val channelName = "location_sharing"
val channel = NotificationChannel(
NOTIFICATION_ID.toString(),
channelName,
NotificationManager.IMPORTANCE_DEFAULT
)
val manager =
(context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager)
manager.createNotificationChannel(channel)
}
private fun getLocation() {
val locationRequest: LocationRequest = LocationRequest.create().apply {
interval = 3000
fastestInterval = 1500
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
maxWaitTime = 2000
}
val locationCallback: LocationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
val locationList = locationResult.locations
if (locationList.isNotEmpty()) {
val location = locationList.last()
Log.d("ServiceDemo", location.latitude.toString()+ " " + System.currentTimeMillis())
}
}
}
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
Toast.makeText(applicationContext, "Permission required", Toast.LENGTH_LONG).show()
return
}else{
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
}
}
}
MainActivity
onCreate method
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
workManager = WorkManager.getInstance(applicationContext)
workRequest = PeriodicWorkRequestBuilder<LocationWorker>(15, TimeUnit.MINUTES)
.setConstraints(constraints)
.build()
workManager!!.enqueueUniquePeriodicWork("Testing WorkManager", ExistingPeriodicWorkPolicy.REPLACE, workRequest as PeriodicWorkRequest)
I wonder how WhatsApp share location because it doesn't ask user to change the battery mode to unrestricted.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
