1

I'm having trouble with ttsvariable . It becomes null, even if the Text to speech object has been initialized.

Inside ShowLabel() function, I want to use tts for texts of firstObject variable. ShowLabel() function receives a List<> of FirebaseVisionImageLabel objects. I'm facing problem on speaking the text inside ShowLabel(). Though the console logs the Boolean to true and the speak() inside OnInit() work.

I have set a checker ttsIsInitialized which is Boolean type, so it needs to be true before the speak() on showLabel() runs. But it gives me null. Any help would be great. If there is a best way to do this, please tell me.

So, For now my issue is tts inside Showlabel() always becomes null. Can someone point out where's my mistake?

This is a project on FirebaseQuickStart
https://github.com/firebase/quickstart-android/tree/master/mlkit

LivePreviewActivity

class LivePreviewActivity : AppCompatActivity(), OnRequestPermissionsResultCallback, TextToSpeech.OnInitListener {

    private var cameraSource: CameraSource? = null
    private var tts: TextToSpeech? = null
    var firstObject = ""


 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_live_preview)

        tts = TextToSpeech(this, this)

    }
fun showLabel(labels: List<FirebaseVisionImageLabel>?) {
        if (!ttsIsInitialized) {
            Log.d(TAG, "TTS not Initialized")
            Log.d("Boolean", ttsIsInitialized.toString())
        } else {
            firstObject = labels!!.first().text
            tts!!.speak(firstObject, TextToSpeech.QUEUE_FLUSH, null, "")
            Log.d("Boolean", ttsIsInitialized.toString())
        }
    }

    override fun onInit(status: Int) {

        if (status == TextToSpeech.SUCCESS) {
            val result = tts!!.setLanguage(Locale.US)

            if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                Log.e("TTS","The Language specified is not supported!")
            } else {
                Log.d("TTS", "Initilization Successful")
                tts!!.speak("This is a test", TextToSpeech.QUEUE_FLUSH, null, "")
                cameraSource?.setMachineLearningFrameProcessor(ImageLabelingProcessor())
                ttsIsInitialized = true
            }
        } else {
            Log.e("TTS", "Initilization Failed!")
        }

    }

ImageLabelingProcessor

class ImageLabelingProcessor : VisionProcessorBase<List<FirebaseVisionImageLabel>>() {

    private val detector: FirebaseVisionImageLabeler = FirebaseVision.getInstance().onDeviceImageLabeler

    override fun stop() {
        try {
            detector.close()
        } catch (e: IOException) {
            Log.e(TAG, "Exception thrown while trying to close Text Detector: $e")
        }
    }

    override fun detectInImage(image: FirebaseVisionImage): Task<List<FirebaseVisionImageLabel>> {
        return detector.processImage(image)
    }

    override fun onSuccess(
        originalCameraImage: Bitmap?,
        labels: List<FirebaseVisionImageLabel>,
        frameMetadata: FrameMetadata,
        graphicOverlay: GraphicOverlay
    ) {
        graphicOverlay.clear()
        originalCameraImage.let { image ->
            val imageGraphic = CameraImageGraphic(graphicOverlay, image)
            graphicOverlay.add(imageGraphic)
        }
        val labelGraphic = LabelGraphic(graphicOverlay, labels)
        graphicOverlay.add(labelGraphic)
        graphicOverlay.postInvalidate()

        val livePreview = LivePreviewActivity()
        livePreview.showLabel(labels)
        livePreview.labels = labels
    }

    override fun onFailure(e: Exception) {
        Log.w(TAG, "Label detection failed.$e")
    }

    companion object {
        private const val TAG = "ImageLabelingProcessor"
    }
}

Logcat

2019-03-09 14:54:50.979 9658-9658/com.google.firebase.samples.apps.mlkit E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.google.firebase.samples.apps.mlkit, PID: 9658
    kotlin.KotlinNullPointerException
        at com.google.firebase.samples.apps.mlkit.kotlin.LivePreviewActivity.showLabel(LivePreviewActivity.kt:76)
        at com.google.firebase.samples.apps.mlkit.kotlin.imagelabeling.ImageLabelingProcessor.onSuccess(ImageLabelingProcessor.kt:51)
        at com.google.firebase.samples.apps.mlkit.kotlin.imagelabeling.ImageLabelingProcessor.onSuccess(ImageLabelingProcessor.kt:19)
        at com.google.firebase.samples.apps.mlkit.kotlin.VisionProcessorBase$detectInVisionImage$1.onSuccess(VisionProcessorBase.kt:98)
        at com.google.android.gms.tasks.zzn.run(Unknown Source:4)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
2019-03-09 14:54:50.983 1881-1952/system_process W/ActivityManager:   Force finishing activity com.google.firebase.samples.apps.mlkit/.kotlin.LivePreviewActivity
2019-03-09 14:54:50.997 9658-9658/com.google.firebase.samples.apps.mlkit I/Process: Sending signal. PID: 9658 SIG: 9
2019-03-09 14:54:51.004 1596-1596/? E/lowmemorykiller: Error writing /proc/9658/oom_score_adj; errno=22
2019-03-09 14:54:51.026 1712-9704/? E/Camera3-OutputStream: getBufferLockedCommon: Stream 0: Can't dequeue next output buffer: Broken pipe (-32)
2019-03-09 14:54:51.026 1712-9704/? E/Camera3-Device: RequestThread: Can't get output buffer, skipping request: Broken pipe (-32)
Ted Edwin
  • 11
  • 3
  • is there any possibility that `onInit()` execute before `OnCreate` ? – Tejas Pandya Mar 09 '19 at 05:00
  • @TejasPandya I'm not sure. Is there any way to see if it executes first? is it possible to delay the override function? – Ted Edwin Mar 09 '19 at 05:57
  • Hi Ted! can you provide the logcat? Also, which code are you receiving from the listener? Finally, When are you executing showLabel() method? My guess is, since the API is asynchronous (synchronous APIs don't need listeners), you are executing the method before the listener is called, but since the listener is executed at some point, you see both the tts member as null, and the correct logs. Try executing showLabel inside the success block of onInit (AKA the listener) – Fco P. Mar 09 '19 at 06:09
  • @TedEdwin please print message in your function and at run time check your log . in which sequence message has been printed – Tejas Pandya Mar 09 '19 at 06:20
  • @FcoP. The tts inside the `onInit()` is working. just the on inside showLabel is null – Ted Edwin Mar 09 '19 at 06:59
  • I get that Ted. But the onInit() method isn't just a function, but a callback. That means, is not executed right away, but rather, you sent it to the TTS framework (in this point: tts = TextToSpeech(this, this) ) to be executed when the TTS instance is ready. That means, even if you call showLabel() after onCreate(), onInit() may not been yet executed, therefore, the tts variable hasn't been initialized yet, thus giving the effect you are seeing. Remove the showLabel() call you have right now, and put it inside the onInit() method to check if this is what's happening. – Fco P. Mar 09 '19 at 18:27

0 Answers0