I'm trying to implement a CoroutineWorker to do some background work in an Android app. The third-party library I'm using uses callbacks like onConnected, onChanged, etc. How can I use this library inside a CoroutineWorker?
This is what I have so far
override suspend fun doWork(): Result {
return try {
val appContext = applicationContext
var mReporter: StepCountReporter?
val mStepCountObserver = object : StepCountReporter.StepCountObserver {
override fun onChanged(count: Int) {
Log.d(APP_TAG, "Step reported : $count")
// This is where the work is completed
}
}
val mConnectionListener = object : HealthDataStore.ConnectionListener {
override fun onConnected() {
Log.d(APP_TAG, "Health data service is connected.")
mReporter = StepCountReporter(mStore!!)
if (isPermissionAcquired) {
mReporter!!.start(mStepCountObserver)
} else {
Log.e(APP_TAG, "permissions not acquired")
}
}
override fun onConnectionFailed(error: HealthConnectionErrorResult) {
Log.d(APP_TAG, "Health data service is not available.")
}
override fun onDisconnected() {
Log.d(APP_TAG, "Health data service is disconnected.")
}
}
mStore = HealthDataStore(appContext, mConnectionListener)
mStore!!.connectService()
// wait for mStepCountObserver.onChanged to be called
} catch (error: Throwable) {
Result.failure()
}
}
I'm trying to finish the coroutine inside mStepCountObserver.onChanged, but it looks like I'm supposed to call Result.success at the end of the function.
You can use suspendCoroutine function, which helps to connect coroutines with Callbacks.
'suspendCoroutine' suspends the coroutine which it is called from and only resumes that coroutine when 'resume()' or 'resumeWithException()' is called.
In your case,
override suspend fun doWork(): Result {
return try {
val outputCount = suspendCoroutine<Int> {
val appContext = applicationContext
var mReporter: StepCountReporter?
val mStepCountObserver = object : StepCountReporter.StepCountObserver {
override fun onChanged(count: Int) {
Log.d(APP_TAG, "Step reported : $count")
// This is where the work is completed
it.resume(Result.success(count))
}
}
val mConnectionListener = object : HealthDataStore.ConnectionListener {
override fun onConnected() {
Log.d(APP_TAG, "Health data service is connected.")
mReporter = StepCountReporter(mStore!!)
if (isPermissionAcquired) {
mReporter!!.start(mStepCountObserver)
} else {
Log.e(APP_TAG, "permissions not acquired")
it.resumeWithException(Exception("permissions not acquired"))
}
}
override fun onConnectionFailed(error: HealthConnectionErrorResult) {
Log.d(APP_TAG, "Health data service is not available.")
it.resumeWithException(Exception("Health data service is not available."))
}
override fun onDisconnected() {
Log.d(APP_TAG, "Health data service is disconnected.")
it.resumeWithException(Exception("Health data service is disconnected."))
}
}
mStore = HealthDataStore(appContext, mConnectionListener)
mStore!!.connectService()
// wait for mStepCountObserver.onChanged to be called
}
Result.success()
} catch (error: Throwable) {
Result.failure()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With