Android Question [SOLVED] *** Using tts.speak causes app to crash

rleiman

Well-Known Member
Licensed User
Longtime User
Greetings everyone,

I'm trying to use tts.speak and I believe I'm not using it correctly.

Can you check my coding and let me know what I'm missing?

I originally thought it needed Talkback to be turned on but the app still crashes on the tts.speak statement with Talkback on and off.

Thanks in advance.

Error displayed in the logs::
b4xmainpage_setupacsformainpageviews (java line: 2796)
java.lang.RuntimeException: Error speaking text.
    at anywheresoftware.b4a.obejcts.TTS.Speak(TTS.java:62)
    at b4a.example.b4xmainpage._setupacsformainpageviews(b4xmainpage.java:2796)
    at b4a.example.b4xmainpage._b4xpage_created(b4xmainpage.java:149)
    at b4a.example.b4xmainpage.callSub(b4xmainpage.java:3732)
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:1066)
    at anywheresoftware.b4a.keywords.Common.CallSubNew2(Common.java:1037)
    at b4a.example.b4xpagesmanager._createpageifneeded(b4xpagesmanager.java:526)
    at b4a.example.b4xpagesmanager._showpage(b4xpagesmanager.java:863)
    at b4a.example.b4xpagesmanager._addpage(b4xpagesmanager.java:203)
    at b4a.example.b4xpagesmanager._addpageandcreate(b4xpagesmanager.java:210)
    at b4a.example.b4xpagesmanager._initialize(b4xpagesmanager.java:714)
    at b4a.example.main._activity_create(main.java:370)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:213)
    at b4a.example.main.afterFirstLayout(main.java:105)
    at b4a.example.main.access$000(main.java:17)
    at b4a.example.main$WaitForLayout.run(main.java:83)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:246)
    at android.app.ActivityThread.main(ActivityThread.java:8633)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
--------- beginning of crash
*** Service (starter) Create ***
** Service (starter) Start **
** Service (servicemodule) Create **
** Service (servicemodule) Start **

tts declaration in Class_Globals::
    Private tts As TTS

Initialising tts::
tts.Initialize("tts")

Statement that crashes the app::
tts.Speak("You are now on the app main screen.", False)
 

drgottjr

Expert
Licensed User
Longtime User
i haven't used tts in a while, but i think you have to wait for the _ready() event before you can speak. not clear from your code that you do that. also, don't forget to release() the engine.
 
Upvote 0

rleiman

Well-Known Member
Licensed User
Longtime User
i haven't used tts in a while, but i think you have to wait for the _ready() event before you can speak. not clear from your code that you do that. also, don't forget to release() the engine.
Thanks for the reply. No, I was not aware that waiting was needed. Can you show sample coding or a link to the coding on waiting for the _ready event for tts.speak ?
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
B4X:
        tts.Initialize("tts")
        Wait For tts_Ready (Success As Boolean)
        Log(Success)

that should do 'er. if success, you're good to go. works for me. hint: keep in mind that speaking a given stream isn't instaneous; the engine has to "compile" your stream (of chars) into sounds. it's usually pretty fast, but there is a process involved.

also, i forget, but you might have to do the waitfor before each utterance. maybe not. see if you can speak something and then speak another thing without the waitfor. if it doesn't work, then try it with the waitfor in between. that should tell you where you stand.

if you still crash, even after the initial waitfor _ready, then i don't know what the deal is. i see you're using b4xpages, so there could be an issue with how b4xpages handles tts.
 
Upvote 0

rleiman

Well-Known Member
Licensed User
Longtime User
B4X:
        tts.Initialize("tts")
        Wait For tts_Ready (Success As Boolean)
        Log(Success)

that should do 'er. if success, you're good to go. works for me. hint: keep in mind that speaking a given stream isn't instaneous; the engine has to "compile" your stream (of chars) into sounds. it's usually pretty fast, but there is a process involved.

also, i forget, but you might have to do the waitfor before each utterance. maybe not. see if you can speak something and then speak another thing without the waitfor. if it doesn't work, then try it with the waitfor in between. that should tell you where you stand.

if you still crash, even after the initial waitfor _ready, then i don't know what the deal is. i see you're using b4xpages, so there could be an issue with how b4xpages handles tts.
Thanks so much for the very helpful replies. šŸ¤—

I will try it and let you know.
 
Upvote 0

rleiman

Well-Known Member
Licensed User
Longtime User
i haven't used tts in a while, but i think you have to wait for the _ready() event before you can speak. not clear from your code that you do that. also, don't forget to release() the engine.
It still crashes on the tts.speak line so it looks like some additional coding is needed for the app since it's in b4xPages.

I added the highlighted lines to Activity_Create in Main:
Sub Activity_Create(FirstTime As Boolean)
    Dim pm As B4XPagesManager
    pm.Initialize(Activity)
    tts.Initialize("tts")
    Wait For tts_Ready (Success As Boolean)
    Log("TTS success from Activity_Create in Main: " & Success)
End Sub

The logs also show "True" for "Success".

I added the highlighted lines to Activity_Resume in Main:
Sub Activity_Resume
    B4XPages.Delegate.Activity_Resume
    B4XPages.MainPage.UpdateMainScreen
   
    tts.Speak("You are now on the app main screen.", False)
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
some additional coding is needed for the app since it's in b4xPages.
Unlikely. There is nothing special about B4XPages. It is just a single regular Activity with Panels for pages instead of separate activities.

The problem is likely to be that you are trying to speak in Activity_Resume but are calling Wait For in Activity_Create. The Wait For in Activity_Create will cause a return to Android which will then immediately run Activity_Resume, which calls Speak and causes the error. Try placing the Speak after the Wait For in Activity_Create to check this.
 
Upvote 0

rleiman

Well-Known Member
Licensed User
Longtime User
Unlikely. There is nothing special about B4XPages. It is just a single regular Activity with Panels for pages instead of separate activities.

The problem is likely to be that you are trying to speak in Activity_Resume but are calling Wait For in Activity_Create. The Wait For in Activity_Create will cause a return to Android which will then immediately run Activity_Resume, which calls Speak and causes the error. Try placing the Speak after the Wait For in Activity_Create to check this.
Thanks for the suggestion. That did the trick. I moved the Wait For into Activity_Resume like this:

B4X:
Sub Activity_Resume
    B4XPages.Delegate.Activity_Resume
    B4XPages.MainPage.UpdateMainScreen
    
    tts.Initialize("tts")
    Wait For tts_Ready (Success As Boolean)
    Log("TTS success from Activity_Create in Main: " & Success)

    If  TalkBackIsActive Then
        tts.Speak("You are now on the app main screen.", False)
    End If

For anyone interested, here's the coding I use for TalkBackIsActive:

B4X:
Sub TalkBackIsActive As Boolean
    
    Dim blnReturnValue As Boolean = False
    Dim context As JavaObject
    Dim AccessibilityManager As JavaObject = context.InitializeContext.RunMethod("getSystemService", _
        Array("accessibility"))

    If AccessibilityManager.IsInitialized Then
        Dim services As List = AccessibilityManager.RunMethod("getEnabledAccessibilityServiceList", _
            Array(1)) 'FEEDBACK_SPOKEN

        If services.Size > 0 Then
            blnReturnValue = True
        End If
    End If
    
    Return blnReturnValue
End Sub
 
Upvote 0
Top