Gebruik Text-to-Speech op Android om binnenkomende berichten te lezen

Apps met interfaces die gebruik maken van spraak, hebben een unieke aantrekkingskracht. Ze hebben de neiging om hun gebruikers het gevoel te geven dat ze iets futuristischs gebruiken. Sinds zijn vroege dagen heeft Android een zeer robuuste tekst-naar-spraak (TTS) -functionaliteit. Dit jaar heeft Google veel hoogwaardige stemmen toegevoegd aan zijn TTS-engine en dat is des te meer reden voor ontwikkelaars om het in hun apps te gebruiken.

In deze tutorial leert u hoe u een eenvoudige app kunt maken - met een minimalistische gebruikersinterface - die tekstberichten kan ontvangen en lezen aan de gebruiker.

voorwaarden

Zorg ervoor dat u de Eclipse ADT-bundel hebt ingesteld. Je kunt het downloaden op de Android Developer-website. Voor het beste resultaat heb je ook een echt Android-apparaat nodig en enkele vrienden die je tekstberichten kunnen sturen.

1. Maak een nieuw project

Start Eclipse en maak een nieuwe Android-applicatie. Bel deze applicatie SMSReader. Als u denkt dat u deze app naar Google Play gaat publiceren om deze met uw vrienden te delen, zorg er dan voor dat u een unieke pakketnaam gebruikt. Stel de Minimaal vereiste SDK naar Android 2.2 en stel de Target SDK naar Android 4.4.

Deze app heeft er een Activiteit. kiezen Activiteit maken en kies Lege activiteit.

Noem maar op Hoofdactiviteit en klik Af hebben.

2. Bewerk het manifest

Deze app heeft drie rechten nodig:

  • RECEIVE_SMS om te weten dat het apparaat een sms heeft ontvangen
  • READ_SMS om die sms te lezen
  • READ_CONTACTS om het telefoonnummer van de afzender aan een naam toe te wijzen (indien mogelijk)

Voeg de volgende regels toe aan uw AndroidManifest.xml.

  

Deze app heeft maar één schermoriëntatie, portret. Bewerk daarom de activiteit tag en voeg het volgende kenmerk toe:

android: screenOrientation = "portret"

Het manifest is nu voltooid.

3. Bewerk strings.xml

Het is niet absoluut noodzakelijk, maar het opslaan van alle strings die de applicatie gebruikt in de res / waarden / strings.xml bestand is een goede gewoonte. Bewerk dit bestand zodat het de volgende inhoud heeft:

  SMSReader Laatste sms Geen START SPREKEN STOP MET PRATEN Oke! Ik zal nu uw berichten hardop voorlezen. Oke! Ik zal nu blijven zwijgen. 

De meeste van deze strings worden gebruikt in de volgende stap.

4. Bewerk de lay-out

Bewerk res / lay-out / activity_main.xml om het volgende toe te voegen:

  • een Tekstweergave om de naam weer te geven van de persoon die de nieuwste sms heeft verzonden
  • een Tekstweergave om de inhoud van de nieuwste SMS weer te geven
  • een ToggleButton om spraakuitvoer in- en uit te schakelen

Na het toevoegen van code voor het positioneren en stylen van deze elementen, zou uw bestand de volgende inhoud moeten hebben:

    

De lay-out voor onze applicatie is nu voltooid.

5. Maak een Helperklasse

We gaan nu een helperklasse maken voor de TTS-engine. Maak een nieuwe Java-klasse en noem die Speaker.java. Deze klasse wordt gebruikt om te voorkomen dat de TTS API rechtstreeks vanuit de. Wordt aangeroepen Activiteit.

Deze klasse implementeert de OnInitListener interface zodat deze weet wanneer de TTS-engine gereed is. We slaan deze klaarstaat op in een booleaanse variabele met de naam klaar. We gebruiken een andere Booleaanse variabele genaamd toegestaan waarvan de waarde is waar alleen als de gebruiker de TTS-engine heeft laten spreken. We voegen ook methoden toe om de waarde van deze variabele te krijgen en in te stellen. Op dit punt, Speaker.java zou de volgende inhoud moeten hebben:

publieke klasse Spreker implementeert OnInitListener private TextToSpeech tts; private boolean ready = false; private boolean toegestaan ​​= false; public Speaker (Context-context) tts = new TextToSpeech (context, dit);  public boolean isAllowed () return allowed;  public void allow (boolean allowed) this.allowed = allowed; 

De OnInitListener interface heeft slechts één methode, onInit. Deze methode wordt aangeroepen wanneer de TTS-engine is geïnitialiseerd. De staat parameter laat ons weten of de initialisatie succesvol was. Zodra we weten dat de initialisatie succesvol was, hebben we de taal van de TTS-engine ingesteld. Dit is belangrijk om spraak te produceren die begrijpelijk is. Voeg de volgende code toe:

@Override public void onInit (int-status) if (status == TextToSpeech.SUCCESS) // Wijzig dit om overeen te komen met uw // locale tts.setLanguage (Locale.US); ready = true;  else ready = false; 

Vervolgens voegen we een methode toe genaamd spreken, die de engine gebruikt om tekst uit te lezen die eraan wordt doorgegeven. Voordat dit wordt gedaan, controleert het of beide toegestaan en de klaar waarden zijn waar. De spraak die het genereert, wordt in de meldingsstream geplaatst.

public void speak (String text) // Speak only if the TTS is ready // en de gebruiker heeft spraak toegestaan ​​(ready && toegestaan) HashMap hash = nieuwe HashMap(); hash.put (TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf (AudioManager.STREAM_NOTIFICATION)); tts.speak (tekst, TextToSpeech.QUEUE_ADD, hash); 

We voegen vervolgens een methode toe die stilte afspeelt voor een opgegeven duur. Met deze methode kunnen we pauzes aan de spraak toevoegen om het een beetje duidelijker te laten klinken. Voeg de volgende code toe aan de implementatie:

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

Voeg ten slotte een methode toe om resources vrij te maken wanneer de TTS-engine niet langer nodig is.

// Maak bronnen vrij openbaar vernietig () tts.shutdown (); 

6. Bewerk de activiteitenklasse

Bewerk MainActivity.java en verklaar alle weergaven die we in de lay-out hebben genoemd. Verklaar twee gehele getallen, LANGE DUUR en KORTE DUUR. Dit zijn slechts waarden die worden doorgegeven aan de spreker's pauze methode.

Verklaar ook a CHECK_CODE geheel getal. Zijn waarde is niet belangrijk. Het wordt doorgegeven aan de startActivityforResult methode en vervolgens gebruikt om het resultaat te identificeren.

Tenslotte, verklaar a spreker object en een Uitzending ontvanger voorwerp.

Op dit punt zou je klas er als volgt uit moeten zien:

public class MainActivity breidt activiteit uit private finale int CHECK_CODE = 0x1; privé finale int LONG_DURATION = 5000; privé finale int SHORT_DURATION = 1200; privé Spreker spreker; privé-schakelaar ToggleButton; private OnCheckedChangeListener toggleListener; privé TextView smsText; privé TextView smsSender; private BroadcastReceiver smsReceiver; 

Voeg een methode toe om te controleren of een TTS-engine op het apparaat is geïnstalleerd. De controle wordt uitgevoerd door gebruik te maken van het resultaat van een ander Activiteit.

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

Wanneer het resultaat is van startActivityForResult arriveert, de onActivityResult methode wordt genoemd. Daarom moeten we het overschrijven. In deze methode initialiseren we het resultaat als het resultaat positief is spreker voorwerp. Als er geen TTS-engine is geïnstalleerd, leiden we de gebruiker om om deze te installeren.

@Override beschermde leegte onActivityResult (int requestCode, int resultCode, Intent-gegevens) 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 (installatie); 

Het is nu tijd om onze te maken Uitzending ontvanger om te gaan met de berichten die het apparaat ontvangt. Wanneer er nieuwe berichten zijn, is het onReceive methode wordt genoemd. We parsen de berichten, die als byte-arrays aankomen, met behulp van de SmsMessage klasse. Zodra het bericht is geparseerd, gebruiken we methoden zoals getDisplayMessageBody en getOriginatingAddress om er zinvolle informatie uit te halen.

Met deze informatie genereren we de tekst die de TTS-engine moet voorlezen. We pauzeren voor LANGE DUUR voor het uitlezen van een nieuwe sms en voor KORTE DUUR tussen de uitingen van de naam van de sms-afzender en de hoofdtekst van de sms.

Voeg de volgende code toe aan de implementatie:

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"); voor (int i = 0; i

We kunnen alleen het telefoonnummer van de afzender uit het bericht extraheren. Om dit nummer aan de naam van een contact toe te wijzen, moeten we gebruik maken van de contacten van de gebruiker. Met de volgende methode worden de contactgegevens gegevens opgevraagd. Als het telefoonnummer niet beschikbaar is in de contacten van de gebruiker, retourneert het eenvoudig de tekenreeks onbekend nummer:

private String getContactName (String-telefoon) Uri uri = Uri.withAppendedPath (PhoneLookup.CONTENT_FILTER_URI, Uri.encode (phone)); String-projectie [] = nieuwe tekenreeks [] ContactsContract.Data.DISPLAY_NAME; Cursorcursor = getContentResolver (). Query (uri, projectie, null, null, null); if (cursor.moveToFirst ()) return cursor.getString (0);  else return "onbekend nummer"; 

Vóór de Uitzending ontvanger kan worden gebruikt, het moet worden geregistreerd. In de volgende methode maken we een IntentFilter voor inkomende sms-berichten en registreer vervolgens onze smsReceiver ervoor:

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

Vervolgens maken we de onCreate methode. Hier initialiseren we alle objecten die we hebben verklaard. We initialiseren de toggleListener om de waarde in te stellen toegestaan in de spreker klasse.

Na deze initialisaties noemen we de checkTTS, initializeSMSReceiver, en registerSMSReceiver methoden.

@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-weergave, 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 ();  

Eindelijk, in de onDestroy methode van de activiteit, we maken de registratie van onze ontvanger ongedaan en schakelen de TTS-engine uit om bronnen vrij te maken.

@Override beschermde leegte onDestroy () super.onDestroy (); unregisterReceiver (smsReceiver); speaker.destroy (); 

7. Uitvoeren en testen

De app is nu klaar om te worden getest. Compileer en voer het uit op een fysiek Android-apparaat. Tik op de schakelknop om spraak in te schakelen en jezelf een sms te sturen vanaf een andere telefoon of vraag een van je vrienden om dit te doen. U zou uw telefoon binnenkort uw SMS kunnen horen voorlezen.

Hier is een voorbeeld van de spraak gegenereerd door de TTS-engine:

Conclusie

In deze zelfstudie hebt u geleerd om niet alleen de API voor tekst-naar-spraak te gebruiken, maar ook om broadcast-ontvangers te gebruiken en om onbegrijpelijke SMS-gegevens beter te begrijpen. U kunt nu doorgaan met het verder aanpassen van deze app aan uw behoeften.