Reputation: 11
I used FusedLocationProviderClient with JobScheduler to get current location all time and it working well when app in background.
But getCurrentLocation() method return Location = null when I tested with Doze and App Standby command.
I faced this issue in OEM devices like samsung, xiaomi, huawei and so on.
Can anyone help me to solve this?
Here is the code,
LocationJob.kt
class LocationJob : JobService() {
private var mLocationRequest: LocationRequest? = null
private var mLocationRequestBuilder: LocationRequest.Builder? = null
private var mFusedLocationClient: FusedLocationProviderClient? = null
private var mLocationCallback: LocationCallback? = null
private val workHandler: Handler = Handler(Looper.getMainLooper())
var workRunnable: Runnable? = null
var handlerThread: HandlerThread? = null
override fun onCreate() {
super.onCreate()
// TODO: Start a background thread to receive location result.
handlerThread = HandlerThread("RequestLocation");
handlerThread!!.start();
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
mLocationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
//Note: this is not called in case of Doze mode in OEM device.
if (locationResult.lastLocation == null) {
Log.e(TAG, "Location missing in callback.")
} else {
Log.e(TAG, "Location callback. ${locationResult.lastLocation}")
}
super.onLocationResult(locationResult)
}
override fun onLocationAvailability(locationAvailability: LocationAvailability) {
super.onLocationAvailability(locationAvailability)
}
}
if (mLocationRequest == null) {
if (mLocationRequestBuilder == null){
mLocationRequestBuilder = LocationRequest.Builder(
Priority.PRIORITY_HIGH_ACCURACY,
sessionManager?.moveOnTripInterval.makeLong()
)
}
mLocationRequestBuilder?.setIntervalMillis()
mLocationRequestBuilder?.setMinUpdateIntervalMillis()
mLocationRequest = mLocationRequestBuilder!!.build()
}
}
override fun onStartJob(params: JobParameters?): Boolean {
Log.e(TAG, "onStartJob")
if (mFusedLocationClient != null) return false
workRunnable = Runnable {
try {
mFusedLocationClient!!.requestLocationUpdates(
mLocationRequest!!, mLocationCallback!!, handlerThread!!.looper
)
Handler(Looper.getMainLooper()).postDelayed({
mFusedLocationClient!!.getCurrentLocation(PRIORITY_HIGH_ACCURACY, null)
.addOnSuccessListener {
Log.e("Loc: $it")
if (it != null) {
val loc = it
println("$TAG: ${loc.latitude},${loc.longitude}")
} else {
Log.e("Loc: is null")
}
}.addOnFailureListener {
println("cancel")
}
}, 10 * 1000)
} catch (unlikely: SecurityException) {
println("$TAG Lost location permission. Could not request updates. ")
}
jobFinished(params, true)
}
workHandler.post(workRunnable!!)
return true
}
MainActivity.kt
class MainActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//trigger LocationJob service
triggerJobService(true)
}
fun triggerJobService(start: Boolean) {
try {
val jobScheduler =
getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
if (start) {
val jobInfo =
JobInfo.Builder(Constant.JOB_ID, ComponentName(this, LocationJob::class.java))
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setRequiresDeviceIdle(false).setRequiresCharging(false).setPersisted(true)
// .setOverrideDeadline(3 * 60 * 1000)
val job = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
jobInfo.setMinimumLatency(Constant.REFRESH_INTERVAL)
.build()
} else {
jobInfo.setPeriodic(Constant.REFRESH_INTERVAL)
.setMinimumLatency(1)
.build()
}
//.setOverrideDeadline(3 * 60 * 1000)
jobScheduler.schedule(job)
} else {
jobScheduler.cancel(Constant.JOB_ID)
}
} catch (e: Exception) {
e.printStackTrace()
return
}
}
}
Upvotes: 1
Views: 397