Inteligentny Dom eHouse może być akustycznie sterowany z androida przy pomocy bibliotek oprogramowania eHouse na platformę android i wbudowanego analizatora (rozpoznawanie) mowy.
Odbywa się przy pomocy wbudowanego w system android analizator mowy, urządzenie do rozpoznawania mowy (speech recognition).
Niniejszy artykuł opisuje jak w kilkudziesięciu liniach kodu źródłowego uruchomić akustyczne sterowanie systemem eHouse ze smartphonów lub tabletów Android.
W tym przykładzie Analizator mowy dla systemu eHouse uruchamia się krótkim przyciśnięciem przycisku sprzętowego wyszukiwania
(Search). Długie przyciśnięcie jest sprzętowo powiązane z wyszukiwaniem przeglądarki internetowej.
Sterowanie akustyczne pracuje w następujący sposób:
- Uruchamiamy analizator mowy (rozpoznawanie) krótko naciskając przycisk
- Pokazuje się okno dialogowe rozpoznawania mowy dla nazwy urządzenia
- Głośno i wyraźnie wymawiamy nazwę sterownika systemu eHouse.
- Rozpoznawanie mowy porównuje nagraną komendę z listą urządzeń na formularzu „RunEvent” w przypadku znalezienia właściwego urządzenia przechodzi do następnego kroku (w przeciwnym wypadku przerywa).
- Pokazuje się okno dialogowe rozpoznawania mowy dla nazwy zdarzenia dla wybranego urządzenia.
- Porównanie jest przetwarzane analizując 3 metody (porównanie dokładne, porównanie nazwy wyjścia oraz porównanie częściowe {zawartość wyniku rozpoznawania mowy w liście zdarzeń}). W przypadku znalezienia właściwego zdarzenia przechodzi do następnego kroku.
- Pokazuje okno dialogowe rozpoznawania mowy komendy dla metody transmisji z systemem eHouse (WIFI, SMS, INTERNET, EMAIL)
- Odpowiedź akustyczna z analizatora mowy jest porównana tabelami zawierającymi zapis fonetyczny tekstu dla każdego sposobu transmisji. Dodawane jest zdarzenie oraz automatycznie wysyłane w przypadku całkowitej zgodności. W przypadku częściowej zgodności nazwy zdarzenia zdarzenie najbliższe jest wybierane z listy, jednak nie jest wysyłane.
Fragmenty kodu źródłowego aplikacji:
@Override
public boolean onKeyDown(int keycode, KeyEvent event ) //oprogramowanie przycisków hardwarowych SmartPhonu
{
if(keycode == KeyEvent.KEYCODE_MENU) //menu dostępne można umieścić widoki i opcje oprogramowania aby nie zajmować przestrzeni ekranu dla menu softwarowego
{
//MessageBox(„Menu”);
}
if (keycode==KeyEvent.KEYCODE_BACK) //back dla smartphonów może nie działać w niektórych opcjach systemu android
{
MessageBox(„Back”);
}
if (keycode==KeyEvent.KEYCODE_HOME) //nadrzędny nie obsługuje
{
MessageBox („Home”);
}
if (keycode==KeyEvent.KEYCODE_SEARCH) //search krótki długi automatycznie obsługa wyszukiwarki
{
// obsługa voice recognition (rozpoznawania mowy do sterowania systemem ehouse)
//uruchamiania zdarzeń eHouse komendami głosowymi
(ehousecommunication.CurrentForm)=ehousecommunication.TEXT_EVENTS; //otwiera formularz tekstowy
SetView(); //wyświetla formularz tekstowy
startVoiceRecognitionActivity(„Device ?”); //uruchamia okno dialogowe rozpoznawania głosu i detekcji słów dla urządzenia (sterownika) 1 etap (2 – zdarzenie) (3-metoda transmisji)
}
if (keycode==KeyEvent.KEYCODE_VOLUME_DOWN) //zmienia wyświetlany ekran (formularz) na poprzedni
{
if (ehousecommunication.CurrentForm<ehousecommunication.FORM_MAX) ehousecommunication.CurrentForm++;
else ehousecommunication.CurrentForm=1;
SetView();
//MessageBox(„-„);
}
if (keycode==KeyEvent.KEYCODE_VOLUME_UP) //zmienia wyświetlany ekran formularz na następny
{
if (ehousecommunication.CurrentForm>0) ehousecommunication.CurrentForm–;
else ehousecommunication.CurrentForm=ehousecommunication.FORM_MAX;
SetView();
//MessageBox(„+”);
}
return false; //inaczej tracimy back z aplikacji i wychodzi
// super.onKeyDown(keycode,event);
}
//Speech Recognition Support
//
public void startVoiceRecognitionActivity(String Caption) { ///Caption nagłówek – opis okna dialogowego analizy mowy
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); //konfiguracja analizatora mowy (speech recognition)
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, „eHouse 4 Android”);
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, Caption); // ustawia opis okna dialogowego
// Given an hint to the recognizer about what the user is going to say
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 15); //zwraca max 15 wyników z analizatora mowy
intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS,300); //długość sygnału ciszy kończący analizę
intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS,300);
// Specify the recognition language.
//Wybiera Domyślny język. w innym przypadku można analizować listę języków i wybrać odpowiedni (jeśli język domyślny urządzenia różni się od języka który zamierzamy analizować)
/*if (!mSupportedLanguageView.getSelectedItem().toString().equals(„Default”)) {
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE,
mSupportedLanguageView.getSelectedItem().toString());
}*/
startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE); //
}
//////////////////////////////////////////////////////////////////////////////////////
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode==SPEECH_REQUEST_CODE) //odtwarzanie dźwięku (synteza tekstu) przez syntezator mowy androida
{
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) //w urządzeniu znajduje się syntezer mowy gotowy do pracy (z obsługą oraz zainstalowanymi pakietami dla akustycznego odtwarzania mowy)
{
// success, create the TTS instance
tts = new TextToSpeech(this, this); //tworzenie instacja syntezera mowy
tts.setLanguage(Locale.US); //język syntezera mowy (można wybrać właściwy o ile jest dostępny)
}
else
{ // missing data, install it // nie ma komponentów syntezera mowy, wymusza instalację z AndroidMarket
Intent installIntent = new Intent();
installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installIntent); //ustawia okno dialogowe instalacji syntezera mowy
}
}
//VOICE REQUEST RESULT – Analizator mowy odebrał sygnał akustyczny
if (requestCode == VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) {
// Fill the list view with the strings the recognizer thought it could have heard
ArrayList<String> matches = data.getStringArrayListExtra(
RecognizerIntent.EXTRA_RESULTS); //lista wyników tekstowych z analizatora mowy
boolean found=false;
if (SpeechItem==SPEECH_DEVICENAME) //pierwszy wynik (akustyczna komenda) nazwa urządzenia
{
for (int i=0;i<matches.size();i++) //dla wszystkich wyników z analizatora mowy
{
for (int k=0;k<RE.DeviceName.getCount();k++) //dla wszystkich nazw sterowników
if (matches.get(i).compareToIgnoreCase(RE.DeviceName.getItemAtPosition(k).toString())==0) //porównuje nazwę sterownika z wynikiem analizatora mowy
{ //jeśli porównanie pasuje
RE.DeviceName.setSelection(k); //wybiera z listy na formularzu RunEvent właściwe urządzenie
SpeechItem=SPEECH_EVENT; //ustawia następny krok analizatora mowy (nazwę zdarzenia dla danego sterownika)
SpeechInvalid=0;
startVoiceRecognitionActivity(„Event ?”); //ponownie uruchamia analizator mowy dla wykrycia nazwy zdarzenia
return;
}
}
}
else
if (SpeechItem==SPEECH_EVENT) //odebrał wyniki z analizatora mowy z nazwą zdarzenia
{
for (int i=0;i<matches.size();i++) //dla wszystkich wyników analizatora mowy
{
for (int k=0;k<RE.EventName.getCount();k++) //dla wszystkich zdarzeń dla wybranego wcześniej sterownika
if (matches.get(i).compareToIgnoreCase(RE.EventName.getItemAtPosition(k).toString())==0) //porównuje wyniki (identyczne)
{
RE.EventName.setSelection(k); //wybiera nazwę zdarzenia z listy na formularzu RunEvent
found=true;
SpeechItem=SPEECH_OK; //flaga następnego kroku analizatora mowy
SpeechInvalid=0;
startVoiceRecognitionActivity(„OK? Internet? SMS? Email?”); //uruchamia następny krok (pytanie o sposób przesłania zdarzenia do systemu (transmisji))
return;
}
}
//jeśli wcześniej nic nie znalazł (dokładnej zgodności nazwy zdarzenia)
for (int i=0;i<matches.size();i++) //dla wszystkich wyników textowych analizatora mowy (dla nazw zdarzeń)
{
for (int k=0;k<RE.EventName.getCount();k++) //dla wszystkich nazw zdarzeń z listy dla urządzenia
if ((matches.get(i)+” (toggle)”).compareToIgnoreCase(RE.EventName.getItemAtPosition(k).toString().replaceAll(„<-„, ” „))==0)
{ //jeśli jest to wyjście cyfrowy i występuje dodatek (toggle) ===przełącz
RE.EventName.setSelection(k); //wybiera zdarzenie przełącz dla danego wyjścia
found=true;
SpeechItem=SPEECH_OK; //ustawia następny krok analizatory mowy
SpeechInvalid=0;
startVoiceRecognitionActivity(„OK? Internet? SMS? Email?”); //uruchamia następny krok analizatora mowy – pytanie o sposób transmisji
return;
}
}
//jeśli wcześniej nic nie znalazł sprawdza częściowe podobieństwo
for (int i=0;i<matches.size();i++) //dla nazw zdarzeń dla wszystkich wyników analizatora mowy
{String mat= matches.get(i).toLowerCase();
for (int k=0;k<RE.EventName.getCount();k++) //dla wszystkich zdarzeń z listy dla wybranego sterownika
{
if (mat.indexOf(RE.EventName.getItemAtPosition(k).toString().toLowerCase())==0) //wyniki tekstowe z analizatora mowy są zawarte w nazwie zdarzenia (cały wynik analizatora w części nazwy zdarzenia z listy)
{
RE.EventName.setSelection(k); Wybiera nazwę zdarzenia
found=true;
// Nie robi nic dalej
/*
SpeechItem=SPEECH_OK; //do wyboru uruchamia sygnał do przesłania zdarzenia
SpeechInvalid=0;
startVoiceRecognitionActivity(„OK? Internet? SMS? Email?”); //uruchamia następny krok analizy mowy dla metody wysłania
*/
//Alternatywnie można odremować ten fragment aby zapytał o wysłanie zdarzenia jeśli jest Właściwe
return;
}
}
}
SpeechItem=SPEECH_DEVICENAME;
}
else
if (SpeechItem==SPEECH_OK) //Analizator mowy w po odebraniu metody transmisji – wybór metody przesłania zdarzeń do systemu
{
for (int i=0;i<matches.size();i++) //dla wszystkich wyników analizatora mowy
{
for (int k=0;k<10;k++)
if (matches.get(i).compareToIgnoreCase(RE.OK[k])==0) //dla wszystkich fonetycznie zapisanych komend dla WiFi
{ //w zmiennej RE.OK
SpeechItem=SPEECH_DEVICENAME;
SpeechInvalid=0;
RE.SubmitEvent(RunEvent.WIFI); //dodaje zdarzenie do kolejki i wysyła przez WIFI
return;
}
}
//jeśli nie WIFI
for (int i=0;i<matches.size();i++)
{
for (int k=0;k<10;k++)
if (matches.get(i).compareToIgnoreCase(RE.vINTERNET[k])==0) //porównuje z komendą dla wysyłania przez internet
{ //tekst fonetycznie zapisany w zmiennej vINTERNET
SpeechItem=SPEECH_DEVICENAME;
SpeechInvalid=0;
RE.SubmitEvent(RunEvent.INTERNET); //wysyła zdarzenie przez internet (EDGE,3G,4G,GPRS lub Inne zewnętrzne łącze w zależności od urządzenia)
return;
}
}
///jeśli nie znalazł komendy dla internetu i wifi
for (int i=0;i<matches.size();i++)
{
for (int k=0;k<10;k++)
if (matches.get(i).compareToIgnoreCase(RE.vSMS[k])==0) //sprawdzamy komendę dla wysłania przez SMS
{ // fonetycznie zapisany tekst w zmienej RE.vSMS
SpeechItem=SPEECH_DEVICENAME;
SpeechInvalid=0;
RE.SubmitEvent(RunEvent.SMS); //dodaje do kolejki zdarzenie i wysyła przez SMS
return;
}
}
//jeśli komenda nie dla SMS, WiFi, Internet
for (int i=0;i<matches.size();i++)
{
for (int k=0;k<10;k++)
if (matches.get(i).compareToIgnoreCase(RE.vEMAIL[k])==0) //porównuje komendę z listą dla wysłania dla Emaili
{ //fonetycznie zapisane tekstem w zmiennej RE.vEMAIL
SpeechItem=SPEECH_DEVICENAME;
SpeechInvalid=0;
RE.SubmitEvent(RunEvent.EMAIL);
return;
}
}
SpeechItem=SPEECH_DEVICENAME;
}
}
super.onActivityResult(requestCode, resultCode, data);
}