Italian [RISOLTO] TTS errore se in Activity_Create

Roberto Tsolakis

Member
Licensed User
Longtime User
Per motivi pratici ho dovuto pulire al massimo la clsPARLA ... e ci sono riuscito
Da qualsiasi activity lo richiamo con un CallSubDelay2(clsPARLA,"Parla",comando_vocale)

Ho notato però una cosa ... se metto CallSubDelay2(clsPARLA,"Parla",comando_vocale) in Activity_Create, la libreria mi da errore
mentre se la metto dietro ad un button ... tutto va a meraviglia.

In teoria se dovessi aprire l'applicazione e fargli dire il titolo ... dovrei far premere un pulsante!
Altre idee ? :)
 

LucaMs

Expert
Licensed User
Longtime User
Non devi lanciare una routine di un modulo di classe direttamente (o indirittamente tramite CallSubDelayed).

Devi creare una variabile oggetto di tipo clsPARLA:

Dim objPARLA As clsPARLA
objPARLA.Initialize

e poi, quando serve, usare i metodi (le routine) dell'oggetto:
objPARLA.NomeMetodo(Parametri)
 

Roberto Tsolakis

Member
Licensed User
Longtime User
Ho creato un modulo di servizio per gestire la TTS ...
Provo a rifare con il modulo di classe ed il tuo suggerimento
 

Roberto Tsolakis

Member
Licensed User
Longtime User
Ho provato a spostare anche nel progetto che mi hai corretto : mTTS.Parla("Funziona.", True)
da Button_Click ad Activity Create ...
e mettendo in Progress_Global ciò che mi hai detto ...

Sempre la solita sfilza di errori ... come se la libreria non potesse sopravvivere ad di vuori di un button.

Lo so sono uno scocciatore

In realtà come funzioni una classe è spiegato molto bene nel tutoriale di Erel ...

Un comando tipo questo:

B4X:
  mTTS.Initialize (Me,"TTS")

Mi fa pensare anche a qualcosa di simile ad una libreria ...
 
Last edited:

Roberto Tsolakis

Member
Licensed User
Longtime User
Qui se ne parla ...
https://www.b4x.com/android/forum/threads/android-text-to-speech-example.7043/page-3

In un modulo di classe ... come controllo il TTS1_Ready ?
Ma dico io non bastava poter fare un controllo tipo:

If TTS1.isReady then .... ?
Sarebbe stato più semplice .. o no ?


Cmq vedo che tu hai fatto qualche controllo :

B4X:
  If SubExists(mCallBack, mEventName & "_Ready") Then
     CallSubDelayed2(mCallBack, mEventName & "_Ready", Success)
   End If

Ma mi sa che non funziona se è in un evento Create.
Spero che sia chiaro che voglio far dire all'applicazione : "BENVENUTO"
 
Last edited:

Roberto Tsolakis

Member
Licensed User
Longtime User
RISOLTO!



Avvio il modulo main senza Layout
in Activity_Create

B4X:
StartService(ClsParla)
StartActivity(Modulo2)

Quindi la libreria ha il tempo di avviarsi .... ed il gioco è fatto!
3 gg per arrivare a questo ... cmq grazie a LucaMS per l'aiuto!


PS: Consiglio di mettere in svariate parti dell'app
il comando :

B4X:
log("Scrivere quello che deve fare l'app")

in modo da capire cosa sta facendo il programma e dove eventualmente si blocca.
Una msgbox o un toastmessageshow non funzionerebbero!
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
Hai risolto trovando una scappatoia, cioè non caricando il layout.

Non è possibile fare:
If TTS1.isReady then .... ?
Sarebbe stato più semplice .. o no ?
perché il comando non è sincrono, non ti da il risultato immediatamente.

Cmq vedo che tu hai fatto qualche controllo :

B4X:
If SubExists(mCallBack, mEventName & "_Ready") Then
     CallSubDelayed2(mCallBack, mEventName & "_Ready", Success)
   End If
Questa routine è un tipico modo per implementare un evento in una tua classe.
Ad esempio, quando scrivi:
Sub Button1_Click
questa è una routine che gestisce un evento.
Io potrei creare una classe che chiami quel Button1_Click (in genere chiamerà un evento inventato da te che non riguarderà l'interfaccia grafica) e in quell'esempio la routine chiamata è _Ready (potevo pure chiamarla Pippo).


Un comando tipo questo:

B4X:
mTTS.Initialize (Me,"TTS")
Mi fa pensare anche a qualcosa di simile ad una libreria ...
Come ti dicevo, mTTS non è un nome appropriato, meglio objTTS, che ti fa subito capire che si tratta di un oggetto.
Comunque, una libreria è una (o più classi); infatti, se tu crei un progetto B4A, ad esempio con la sola Main e una tua classe, poi puoi compilare il progetto come libreria e le funzionalità delle tua classe (le routine ma anche le proprietà) saranno disponibili tramite la libreria creata.



PS: Consiglio di mettere in svariate parti dell'app
il comando :

B4X:
log("Scrivere quello che deve fare l'app")
in modo da capire cosa sta facendo il programma e dove eventualmente si blocca.
Una msgbox o un toastmessageshow non funzionerebbero!
Già, verissimo. Infatti ho pubblicato una mia utility che non molte persone hanno scaricato (incompetenti :p), AddLogs (guarda la mia signature-firma)
 
Last edited:

Roberto Tsolakis

Member
Licensed User
Longtime User
Sto facendo un app per bimbi piccoli (io ho un bimbo piccolo e gli ho regalato un tabler ... quale buon motivo per insegnargli qualcosa?) ... e il modulo TTS mi è indispensabile.
Il riconoscimento vocale l'ho previsto tra le funzioni, ma il vero problema è proprio il TTS che non è immediato.
Ma lasciando qualche secondo di tempo dopo aver avviato la libreria ... il problema si risolve.

Ho provato a mettere il codice in una classe ... ma risulta più complicato che in un modulo di servizio.
Ma ora ho letto che i moduli di servizio non vanno in stand by ... e questo ne va tenuto conto per eventuali problemi-

La app voglio che sia il più pulito possibile ... cosi se ci dovessi mettere le mani fra 5 anni, sarebbe ben leggibile.
Inoltre sto cercando di farla funzionare su qualsiasi dispositivo e quindi il desiner non lo voglio praticamente utilizzare ... e questo mi da problemi con gli eventi, che normalmente sono banali utilizzando il desiner.
 

LucaMs

Expert
Licensed User
Longtime User
Ho usato (tanto per provare) il TTS proprio agli inizi, oltre due anni fa.

Adesso ho sottomano un esempio. E' semplicissimo, tutto nell'Activity Main:

1) dichiara un oggetto di tipo TTS nella Process_Globals (TTS1);
2) nella Activity_Resume inizializza TTS1, se non lo è già, passandogli come nome evento (meglio chiamarlo "prefisso evento", direi) "TTS1";
3) imposta la lingua (l'esempio ne consente la scelta tramite uno Spinner; ovviamente si può impostare direttamente);
4) nell'evento TTS1_Ready (che indica appunto che il "sistema" è pronto) vengono abilitate le view (si potrebbe fare anche altro, come impostare una variabile globale);
5) da questo momento gli fai pronunciare quello che ti pare.

Ora, tutto questo si può fare sia direttamente in un'Activity, sia in modulo di servizio, sia in una classe; ma non vedo perché non farlo in un'activity, magari non la Main.
 
Top