WorkManager observe retrofit progress

Viewed 547

I am uploading the file using Kotlin workmanager. In CoroutineWorkmanager, I do file upload with a suspend upload function. I want to observe retrofit progress and show it on ui. I can see the retrofit progress state but I cannot observe it in workManager.

My request body class where I can see the retrofit progress state :

class ProgressRequestBody : RequestBody {
    val mFile: File
    val ignoreFirstNumberOfWriteToCalls : Int

    constructor(mFile: File) : super(){
        this.mFile = mFile
        ignoreFirstNumberOfWriteToCalls = 0
    }

    constructor(mFile: File, ignoreFirstNumberOfWriteToCalls : Int) : super(){
        this.mFile = mFile
        this.ignoreFirstNumberOfWriteToCalls = ignoreFirstNumberOfWriteToCalls
    }
    var numWriteToCalls = 0

    private val _shared = MutableStateFlow<Float>(0F)
    val shared : StateFlow<Float> = _shared
    
    override fun contentType(): MediaType? {
        return "image/*".toMediaTypeOrNull()
    }

    @Throws(IOException::class)
    override fun contentLength(): Long {
        return mFile.length()
    }

    @Throws(IOException::class)
    override fun writeTo(sink: BufferedSink) {
        numWriteToCalls++

        val fileLength = mFile.length()
        val buffer = ByteArray(DEFAULT_BUFFER_SIZE)
        val `in` = FileInputStream(mFile)
        var uploaded: Long = 0

        try {
            var read: Int
            var lastProgressPercentUpdate = 0.0f
            read = `in`.read(buffer)
            while (read != -1) {

                uploaded += read.toLong()
                sink.write(buffer, 0, read)
                read = `in`.read(buffer)

                if (numWriteToCalls > ignoreFirstNumberOfWriteToCalls ) {
                    val progress = (uploaded.toFloat() / fileLength.toFloat()) * 100f
                    if (progress - lastProgressPercentUpdate > 1 || progress == 100f) {
                        _shared.value = progress
                        Log.d("progress", "${shared.value}")
                        lastProgressPercentUpdate = progress
                    }
                }
            }
        } finally {
            `in`.close()
        }
    }


    companion object {

        private val DEFAULT_BUFFER_SIZE = 2048
    }
}

The worker I uploaded the file to:

class UploadWorker @WorkerInject constructor(
    private val  repository: Repository,
    @Assisted context: Context,
    @Assisted params: WorkerParameters
): CoroutineWorker(context, params) {

    private lateinit var result: UploadResult
    
    @ObsoleteCoroutinesApi
    @OptIn(ExperimentalCoroutinesApi::class)
    @SuppressLint("RestrictedApi")
    override suspend fun doWork(): Result {
       return try{
          
           val requestBody = ProgressRequestBody(File(fileUri!!.toUri().path))
           val multipartBody = prepareBody(fileUri!!.toUri(), photoPart)

           progressState(requestBody)


           upload(multipartBody)
           
           Result.Success()
        }catch(e :Exception){
            Result.failure()
        }
    }

    private fun prepareBody( ): MultipartBody.Part {

        return MultipartBody.Part.createFormData("photo", "photo", "image/*")
    }

    suspend fun upload(
        multipartBody: MultipartBody.Part,
    ) {
        repository.uploadPhotos(
               multipartBody
           ).collect{ result ->
            if (result is Result.Success) {
                this.result = result.data
            }
        }
    }

     private suspend fun progressState(photoPart: ProgressRequestBody) {
        coroutineScope {
            launch {
                photoPart.shared.collect{
                    setProgress(workDataOf(PROGRESS to it))
                }
            }
        }
    }
}

While this way I can't run the worker. I am getting the following error from the worker:

 java.util.concurrent.CancellationException: Task was cancelled.
        at androidx.work.impl.utils.futures.AbstractFuture.cancellationExceptionWithCause(AbstractFuture.java:1184)
        at androidx.work.impl.utils.futures.AbstractFuture.getDoneValue(AbstractFuture.java:514)
0 Answers
Related