setProgressAsync in ListenableWorker not sending update to LiveData

1.9k Views Asked by At

I have to implement a library that creates it's own thread to do the execution. Now, have to start the library-execution in background and hence using ListenableWorker.

But, setProgressAsync is not updating the LiveData.

Here is the code,

class ForegroundWorker(appContext: Context, params: WorkerParameters) :
ListenableWorker(appContext, params) {

private val notificationManager = appContext.getSystemService(NotificationManager::class.java)

override fun startWork(): ListenableFuture<Result> {
    Log.d(TAG, "Start job")

    return CallbackToFutureAdapter.getFuture { completer: CallbackToFutureAdapter.Completer<Result> ->

        val callback: AsyncCallback = object : AsyncCallback {
            var successes: Int = 0
            override fun onError(failure: String?) {
                completer.setException(Throwable())
            }

            override fun onSuccess(foo: String?) {
                ++successes
                setProgressAsync(workDataOf(Progress to successes))
                //completer.set(Result.success(workDataOf(Progress to successes)))
                if (successes == 100) {
                    completer.set(Result.success(workDataOf(Progress to successes)))
                }
            }
        }

        //completer.addCancellationListener(cancelDownloadsRunnable, executor)

        //for (i in 0..99) {
        downloadAsynchronously("https://www.google.com", callback)
        //}
        callback
    }

    /*createNotificationChannel()

    val notification = NotificationCompat.Builder(applicationContext, channelId)
        .setSmallIcon(R.mipmap.ic_launcher)
        .setContentTitle("Important background job")
        .build()

    val foregroundInfo = ForegroundInfo(NOTIFICATION_ID, notification)
    setForegroundAsync(foregroundInfo)

    for (i in 0..100) {
        setProgressAsync(workDataOf(Progress to i))
        showProgress(i)
        GlobalScope.launch {
            delay(delayDuration)
        }
    }

    Log.d(TAG, "Finish job")
    return Result.success()*/
}

private fun downloadAsynchronously(s: String, callback: AsyncCallback) {
    createNotificationChannel()

    val notification = NotificationCompat.Builder(applicationContext, channelId)
        .setSmallIcon(R.mipmap.ic_launcher)
        .setContentTitle("Important background job")
        .build()

    val foregroundInfo = ForegroundInfo(NOTIFICATION_ID, notification)
    setForegroundAsync(foregroundInfo)

    for (i in 0..1000) {
        setProgressAsync(workDataOf(Progress to i))
        showProgress(i)
        GlobalScope.launch {
            delay(delayDuration)
        }
        callback.onSuccess("")

    }

}

  private fun showProgress(progress: Int) {
    val notification = NotificationCompat.Builder(applicationContext, 
   channelId)
        .setSmallIcon(R.mipmap.ic_launcher)
        .setContentTitle("Important background job")
        .setProgress(100, progress, false)
        .build()
    notificationManager?.notify(NOTIFICATION_ID, notification)
}

private fun createNotificationChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        var notificationChannel =
            notificationManager?.getNotificationChannel(channelId)
        if (notificationChannel == null) {
            notificationChannel = NotificationChannel(
                channelId, TAG, NotificationManager.IMPORTANCE_LOW
            )
            notificationManager?.createNotificationChannel(notificationChannel)
        }
    }
}

companion object {

    const val NOTIFICATION_ID = 42
    const val TAG = "ForegroundWorker"
    const val channelId = "Job progress"
    const val Progress = "Progress"
    private const val delayDuration = 100L
}

interface AsyncCallback {
    fun onSuccess(foo: String?)
    fun onError(failure: String?)
}
}

and the livedata,

class MainActivity : AppCompatActivity() {

lateinit var binding: ActivityMainBinding

val workManager = WorkManager.getInstance(this)
var workRequest: OneTimeWorkRequest = OneTimeWorkRequest.from(ForegroundWorker::class.java)

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

   
    /*val workManager = WorkManager.getInstance(this)
    val workRequest = OneTimeWorkRequest.from(ForegroundWorker::class.java)*/

    // if (SharedPreferenceHelper.workRequestId != "") {
    workManager.getWorkInfoByIdLiveData(workRequest.id)
        .observe(this, Observer { workInfo: WorkInfo? ->
            if (workInfo != null) {
                val progress = workInfo.progress
                val value = progress.getInt(Progress, 0)
                binding.progressBar.progress = value
            }
        })
    //}
    workManager.enqueue(workRequest)
}
}

For some reason, setProgressAsync is not updating the Livedata.

0

There are 0 best solutions below