Utilizza Text-to-Speech su Android per leggere i messaggi in arrivo

Le app con interfacce che fanno uso della voce hanno un fascino unico. Tendono a far sentire i propri utenti che stanno usando qualcosa di futuristico. Fin dai suoi primi giorni, Android ha una funzionalità TTS (text-to-speech) molto solida. Quest'anno, Google ha aggiunto molte voci di alta qualità al suo motore TTS e questo è un motivo in più per gli sviluppatori di utilizzarlo nelle loro app.

In questo tutorial imparerai come creare una semplice app, con un'interfaccia utente minimalista, in grado di ricevere messaggi di testo e leggerli all'utente.

Prerequisiti

Assicurati di avere impostato il pacchetto Eclipse ADT. Puoi scaricarlo dal sito web degli sviluppatori Android. Per ottenere i migliori risultati, avrai anche bisogno di un vero dispositivo Android e di alcuni amici che possono inviarti messaggi di testo.

1. Crea un nuovo progetto

Avvia Eclipse e crea una nuova applicazione Android. Chiama questa applicazione SMSReader. Se pensi di pubblicare questa app su Google Play per condividerla con i tuoi amici, assicurati di utilizzare un nome di pacchetto univoco. Impostare il SDK richiesto minimo a Android 2.2 e impostare il SDK target a Android 4.4.

Questa app ne avrà uno Attività. Selezionare Crea attività e scegliere Attività vuota.

Nominalo Attività principale e fare clic finire.

2. Modifica il manifest

Questa app richiede tre autorizzazioni:

  • RECEIVE_SMS per sapere che il dispositivo ha ricevuto un SMS
  • READ_SMS per leggere quel SMS
  • READ_CONTACTS per mappare il numero di telefono del mittente su un nome (se possibile)

Aggiungi le seguenti linee al tuo AndroidManifest.xml.

  

Questa app avrà solo un orientamento dello schermo, verticale. Pertanto, modifica il file attività tag e aggiungi il seguente attributo ad esso:

Android: screenOrientation = "ritratto"

Il manifest è ora completo.

3. Modifica strings.xml

Non è assolutamente necessario, ma memorizza tutte le stringhe che l'applicazione utilizza nel res / valori / strings.xml il file è una buona pratica. Modifica questo file in modo che abbia il seguente contenuto:

  SMSReader Ultimo SMS Nessuna INIZIA PARLARE FERMATE DI PARLARE Va bene! Leggerò i tuoi messaggi ad alta voce per te ora. Va bene! Rimarrò in silenzio ora. 

La maggior parte di queste stringhe viene utilizzata nel passaggio successivo.

4. Modifica il layout

modificare res / layout / activity_main.xml aggiungere il seguente:

  • un TextView per visualizzare il nome della persona che ha inviato l'ultimo SMS
  • un TextView per visualizzare il contenuto degli ultimi SMS
  • un Interruttore per attivare e disattivare l'uscita vocale

Dopo aver aggiunto il codice per il posizionamento e lo styling di questi elementi, il tuo file dovrebbe avere il seguente contenuto:

    

Il layout per la nostra applicazione è ora completo.

5. Creare una classe di supporto

Ora creeremo una classe di supporto per il motore TTS. Crea una nuova classe Java e chiamala Speaker.java. Questa classe viene utilizzata per evitare di chiamare l'API TTS direttamente dal Attività.

Questa classe implementa il OnInitListener interfaccia in modo che sappia quando il motore TTS è pronto. Memorizziamo questo stato pronto in una variabile booleana chiamata pronto. Usiamo un'altra variabile booleana chiamata permesso di chi è il valore vero solo se l'utente ha permesso al motore TTS di parlare. Aggiungiamo anche metodi per ottenere e impostare il valore di questa variabile. A questo punto, Speaker.java dovrebbe avere il seguente contenuto:

speaker di classe pubblica implementa OnInitListener private TextToSpeech tts; ready booleano privato = falso; booleano privato consentito = falso; Speaker pubblico (contesto contestualizzato) tts = new TextToSpeech (context, this);  public boolean isAllowed () return allowed;  public void allow (boolean consentito) this.allowed = allowed; 

Il OnInitListener l'interfaccia ha solo un metodo, onInit. Questo metodo viene chiamato quando il motore TTS è stato inizializzato. Il stato parametro ci consente di sapere se l'inizializzazione ha avuto successo. Una volta che sappiamo che l'inizializzazione ha avuto successo, impostiamo la lingua del motore TTS. Questo è importante per produrre un discorso comprensibile. Aggiungi il seguente codice:

@Override public void onInit (stato int) if (status == TextToSpeech.SUCCESS) // Cambia questo in modo che corrisponda alla tua // locale tts.setLanguage (Locale.US); pronto = vero;  else ready = false; 

Successivamente, aggiungiamo un metodo chiamato parlare, che usa il motore per leggere qualsiasi testo che gli viene passato. Prima di farlo, controlla se entrambi permesso e il pronto i valori sono vero. Il discorso che genera viene inserito nel flusso di notifica.

public public speak (String text) // Parla solo se TTS è pronto // e l'utente ha permesso la parola se (ready && allowed) HashMap hash = nuova HashMap(); hash.put (TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf (AudioManager.STREAM_NOTIFICATION)); tts.speak (text, TextToSpeech.QUEUE_ADD, hash); 

Quindi aggiungiamo un metodo che riproduce il silenzio per una durata specificata. Usando questo metodo, possiamo aggiungere pause al discorso per renderlo un po 'più chiaro. Aggiungi il seguente codice all'implementazione:

public void pause (int duration) tts.playSilence (duration, TextToSpeech.QUEUE_ADD, null); 

Infine, aggiungi un metodo per liberare risorse quando il motore TTS non è più necessario.

// Liberare risorse public void destroy () tts.shutdown (); 

6. Modificare la classe di attività

modificare MainActivity.java e dichiara tutti i punti di vista che abbiamo menzionato nel layout. Dichiarare due numeri interi, LUNGA DURATA e BREVE DURATA. Questi sono solo valori che vengono passati a altoparlante'S pausa metodo.

Dichiara anche a CHECK_CODE numero intero. Il suo valore non è importante. È passato al startSubActivity metodo e quindi utilizzato per identificare il risultato.

Infine, dichiara a altoparlante oggetto e a BroadcastReceiver oggetto.

A questo punto, la tua classe dovrebbe assomigliare a questa:

public class MainActivity estende Activity private final int CHECK_CODE = 0x1; private final int LONG_DURATION = 5000; private final int SHORT_DURATION = 1200; altoparlante privato; interruttore ToggleButton privato; private OnCheckedChangeListener toggleListener; TextView privato smsText; TextView privato smsSender; BroadcastReceiver privato smsReceiver; 

Aggiungi un metodo per verificare se un motore TTS è installato sul dispositivo. Il controllo viene eseguito utilizzando il risultato di un altro Attività.

private void checkTTS () Intent check = new Intent (); check.setAction (TextToSpeech.Engine.ACTION_CHECK_TTS_DATA); startActivityForResult (check, CHECK_CODE); 

Quando il risultato di startSubActivity arriva, il onActivityResult il metodo è chiamato. Pertanto, abbiamo bisogno di ignorarlo. In questo metodo, se il risultato è positivo, inizializziamo il altoparlante oggetto. Se non è installato alcun motore TTS, reindirizziamo l'utente per installarlo.

@Override protetto void onActivityResult (int requestCode, int resultCode, Intent data) if (requestCode == CHECK_CODE) if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) speaker = new Speaker (this);  else Intent install = new Intent (); install.setAction (TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA); startActivity (installazione); 

Ora è il momento di creare il nostro BroadcastReceiver per gestire i messaggi ricevuti dal dispositivo. Ogni volta che ci sono nuovi messaggi, è OnReceive il metodo è chiamato. Analizziamo i messaggi, che arrivano come array di byte, usando il smsmessage classe. Una volta che il messaggio è stato analizzato, usiamo metodi come getDisplayMessageBody e getOriginatingAddress per estrarre informazioni significative da esso.

Con queste informazioni, generiamo il testo che il motore TTS dovrebbe leggere. Ci fermiamo per LUNGA DURATA prima di leggere un nuovo SMS e per BREVE DURATA tra le espressioni del nome del mittente dell'SMS e il corpo dell'SMS.

Aggiungi il seguente codice all'implementazione:

private void initializeSMSReceiver () smsReceiver = new BroadcastReceiver () @Override public void onReceive (Context context, Intent intent) Bundle bundle = intent.getExtras (); if (bundle! = null) Object [] pdus = (Object []) bundle.get ("pdus"); per (int i = 0; i

Possiamo solo estrarre il numero di telefono del mittente dal messaggio. Per mappare questo numero al nome di un contatto, dobbiamo fare uso dei contatti dell'utente. Il seguente metodo interroga i dati dei contatti. Se il numero di telefono non è disponibile nei contatti dell'utente, restituisce semplicemente la stringa numero sconosciuto:

private String getContactName (String phone) Uri uri = Uri.withAppendedPath (PhoneLookup.CONTENT_FILTER_URI, Uri.encode (phone)); String projection [] = new String [] ContactsContract.Data.DISPLAY_NAME; Cursore cursor = getContentResolver (). Query (uri, proiezione, null, null, null); if (cursor.moveToFirst ()) return cursor.getString (0);  else return "unknown number"; 

Prima di BroadcastReceiver può essere usato, deve essere registrato. Nel seguente metodo, creiamo un IntentFilter per i messaggi di testo in arrivo e quindi registrare il nostro smsReceiver per questo:

private void registerSMSReceiver () IntentFilter intentFilter = new IntentFilter ("android.provider.Telephony.SMS_RECEIVED"); registerReceiver (smsReceiver, intentFilter); 

Successivamente, creiamo il onCreate metodo. Ecco dove inizializziamo tutti gli oggetti che abbiamo dichiarato. Inizializziamo il toggleListener per impostare il valore di permesso nel altoparlante classe.

Dopo queste inizializzazioni, chiamiamo il checkTTS, initializeSMSReceiver, e registerSMSReceiver metodi.

@Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); toggle = (ToggleButton) findViewById (R.id.speechToggle); smsText = (TextView) findViewById (R.id.sms_text); smsSender = (TextView) findViewById (R.id.sms_sender); toggleListener = new OnCheckedChangeListener () @Override public void onCheckedChanged (CompoundButton view, boolean isChecked) if (isChecked) speaker.allow (true); speaker.speak (getString (R.string.start_speaking));  else speaker.speak (getString (R.string.stop_speaking)); speaker.allow (false); ; toggle.setOnCheckedChangeListener (toggleListener); checkTTS (); initializeSMSReceiver (); registerSMSReceiver ();  

Finalmente, nel OnDestroy metodo dell'attività, annulliamo la registrazione del nostro ricevitore e spegniamo il motore TTS per liberare risorse.

@Override protected void onDestroy () super.onDestroy (); unregisterReceiver (smsReceiver); speaker.destroy (); 

7. Esegui e prova

L'app è ora pronta per essere testata. Compilalo ed eseguilo su un dispositivo Android fisico. Tocca il pulsante di attivazione / disattivazione per attivare la voce e inviare un SMS da un altro telefono o chiedere a uno dei tuoi amici di farlo. Presto dovresti sentire il tuo telefono leggere gli SMS per te.

Ecco un esempio del discorso generato dal motore TTS:

Conclusione

In questo tutorial, hai imparato non solo a usare l'API text-to-speech, ma anche a usare i ricevitori broadcast e a dare un senso ai dati raw degli SMS. Ora puoi continuare a personalizzare ulteriormente questa app in base alle tue esigenze.