1

I am trying to run a Google ML Kit function and the result will be in callback and need to pass that value as a return type for the method in which it was executing in Kotlin. I tried some of the samples of Kotlin coroutines but still I am missing something and it was failing. I am still learning Kotlin.

internal fun processImageSync(image: InputImage) : String{
        var doctype = ""
        val recognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS)
        recognizer.process(image)
            .addOnSuccessListener { visionText ->
                var texttoscan = visionText.text.trim()
                doctype = findstr(texttoscan)    
            }
            .addOnFailureListener { 
            }
    return doctype;
    }

How can I solve the issue?

halfer
  • 19,824
  • 17
  • 99
  • 186
Prabhakaran
  • 1,264
  • 2
  • 20
  • 47
  • the entire point of async methods is that you shouldn't run them synchronous. it would block the main thread then. You just need to figure out a way to do whatever you want to do with the result inside the callback – Ivo Mar 24 '22 at 06:55
  • You can convert it to a suspend function using [`suspendCoroutine`](https://stackoverflow.com/a/71025162/3585796), but then you have to run it from a coroutine scope – Phil Dukhov Mar 24 '22 at 08:18
  • @Ivo coroutines are asynchronous, but you can run a piece of code synchronously inside them, thus having the flow of the one particular asynchronous coroutine synchronously wait for this code, which is ultimately what coroutines are for. Google itself is moving away from callbacks in favor of this approach and having to work around callbacks if you have a functioning environment with coroutines is a major pain. In other words, the question is very valid, even though it seems that the author does not fully understand coroutines themselves. – NoHarmDan Jan 12 '23 at 13:54

1 Answers1

2

Use kotlinx-coroutines-play-services module

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.0")
}

Use extension Task.await

internal suspend fun processImageSync(image: InputImage): String {
    val recognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS)
        
    return recognizer.process(image)
        .await()
        .let { visionText -> findstr(visionText.text.trim()) }
}