Rozpoznawanie mowy pozwala stworzyć całkowicie bezdotykowy interfejs. Google Glass oferuje 3 metody wprowadzania głosowego.
Główne polecenia głosowe uruchamiają oprogramowanie Glassware na karcie głównej, kontekstowe polecenia głosowe mogą wykonywać działania w ramach aktywności, a systemowe rozpoznawanie mowy umożliwia użytkownikowi odbieranie własnych komunikatów głosowych.
Główne polecenia głosowe
Te polecenia głosowe uruchamiają Glassware na karcie głównej (karta zegara). Gdy zadeklarujesz główne polecenie głosowe, Google Glass automatycznie utworzy jako element zastępczy menu dotykowego, jeśli użytkownicy postanowią uruchomić urządzenie Glass za pomocą dotknięcia karty głównej.
Aby dodać polecenie głosowe do menu głównego OK Google:
Utwórz zasób XML dla polecenia głosowego w
res/xml/<my_voice_trigger>.xml
, które korzysta z jednego z dotychczasowych poleceń głosowych zdefiniowanych wVoiceTriggers.Command
. Oto przykład użycia polecenia „Rozpocznij bieg”.<?xml version="1.0" encoding="utf-8"?> <trigger command="START_A_RUN" />
Aby utworzyć polecenie głosowe, które poprosi użytkownika o wypowiedzenie dodatkowych słów przed rozpoczęciem aktywności lub usługi, dodaj też element
input
. Może Ci się to przydać na przykład wtedy, gdy używasz opcji „Opublikuj aktualizację”.<?xml version="1.0" encoding="utf-8"?> <trigger command="POST_AN_UPDATE"> <input prompt="@string/glass_voice_prompt" /> </trigger>
Zarejestruj filtr intencji, używając działania
com.google.android.glass.action.VOICE_TRIGGER
w pliku manifestu Androida. Filtr intencji uruchamia Twoją aktywność lub usługę, jeśli wykryje, że użytkownik wydaje polecenie głosowe.<?xml version="1.0" encoding="utf-8"?> <application ...> <activity | service ...> <intent-filter> <action android:name= "com.google.android.glass.action.VOICE_TRIGGER" /> </intent-filter> <meta-data android:name="com.google.android.glass.VoiceTrigger" android:resource="@xml/my_voice_trigger" /> </activity | service> // ... </application>
Zadeklaruj atrybut
android:icon
swojej aktywności lub usługi. Dzięki temu Google Glass może wyświetlić ikonę szkła Glass w menu ok, Glass.<activity |service android:icon="@drawable/my_icon" ...> ... </activity | service>
Jeśli polecenie głosowe użyje polecenia głosowego i uruchomi aktywność, pobierz dowolny transkrypcję tekstu za pomocą tego kodu (na przykład w
onResume()
):ArrayList<String> voiceResults = getIntent().getExtras() .getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
Jeśli polecenie głosowe uruchomi usługę, intencja dodatkowa będzie dostępna w wywołaniu zwrotnym
onStartCommand()
:@Override public int onStartCommand(Intent intent, int flags, int startId) { ArrayList<String> voiceResults = intent.getExtras() .getStringArrayList(RecognizerIntent.EXTRA_RESULTS); // ... }
Ustawianie ograniczeń
Jeśli do uruchamiania Glassware potrzebujesz co najmniej jednej z tych funkcji, wskaż je w zasobie res/xml/<my_voice_trigger>.xml
.
Jeśli funkcje są niedostępne, Google Glass wyłączy polecenie głosowe:
camera
network
microphone
<trigger command="POST_AN_UPDATE"> <constraints camera="true" network="true" /> </trigger>
Kontekstowe polecenia głosowe
Kontekstowe polecenia głosowe pozwalają użytkownikom wykonywać czynności pochodzące z aktywności. Kontekstowe polecenia głosowe tworzy się za pomocą standardowych interfejsów API menu na Androidzie, ale użytkownicy mogą wywoływać pozycje menu za pomocą poleceń głosowych zamiast dotyku.
Aby włączyć kontekstowe polecenia głosowe związane z określoną aktywnością:
Wywołaj
getWindow().requestFeature(
WindowUtils.FEATURE_VOICE_COMMANDS
)
w odpowiedniej aktywności, aby włączyć kontekstowe polecenia głosowe. Gdy ta funkcja jest włączona, menu „OK Glass” pojawia się w stopce ekranu, gdy zadanie zostanie zaznaczone.Zastąp
onCreatePanelMenu()
i rozpatruj zgłoszenia, w których włączonoWindowUtils.FEATURE_VOICE_COMMANDS
. Jeśli włączysz tę opcję, tutaj możesz przeprowadzić jednorazową konfigurację menu, na przykład zawyżyć zasób menu lub wywołać metodyMenu.add()
, aby utworzyć system menu głosowego.Zastąp
onMenuItemSelected()
obsługą poleceń głosowych, gdy użytkownicy je wypowiadają. Gdy użytkownik wybierze opcję z menu, polecenie głosowe "ok, Glass" automatycznie pojawi się w sekcji stopki ekranu, gdzie będzie można zaakceptować nowe polecenie. Będą one aktywne, dopóki aktywność będzie aktywna.Ten kod włącza kontekstowe polecenia głosowe, w razie potrzeby zapełnia zasób menu i obsługuje polecenia głosowe:
public class ContextualMenuActivity extends Activity { @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); // Requests a voice menu on this activity. As for any other // window feature, be sure to request this before // setContentView() is called getWindow().requestFeature(WindowUtils.FEATURE_VOICE_COMMANDS); setContentView(R.layout.activity_main); } @Override public boolean onCreatePanelMenu(int featureId, Menu menu) { if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) { getMenuInflater().inflate(R.menu.main, menu); return true; } // Pass through to super to setup touch menu. return super.onCreatePanelMenu(featureId, menu); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onMenuItemSelected(int featureId, MenuItem item) { if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) { switch (item.getItemId()) { case R.id.dogs_menu_item: // handle top-level dogs menu item break; case R.id.cats_menu_item: // handle top-level cats menu item break; case R.id.lab_menu_item: // handle second-level labrador menu item break; case R.id.golden_menu_item: // handle second-level golden menu item break; case R.id.calico_menu_item: // handle second-level calico menu item break; case R.id.cheshire_menu_item: // handle second-level cheshire menu item break; default: return true; } return true; } // Good practice to pass through to super if not handled return super.onMenuItemSelected(featureId, item); } }
Oto przykład zasobu menu używanego w poprzedniej aktywności. Zwróć uwagę, że możesz tworzyć zagnieżdżone pozycje menu dla hierarchicznego systemu menu głosowego. W przykładzie poniżej pierwsza pozycja w menu jest widoczna jako: OK, Glass, Pokaż psy, Labrador.
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Use the constants defined in the ContextualMenus.Command enum--> <item android:id="@+id/dogs_menu_item" android:title="@string/show_me_dogs"> <menu> <item android:id="@+id/lab_menu_item" android:title="@string/labrador" /> <item android:id="@+id/golden_menu_item" android:title="@string/golden" /> </menu> </item> <item android:id="@+id/cats_menu_item" android:title="@string/show_me_cats"> <menu> <item android:id="@+id/cheshire_menu_item" android:title="@string/cheshire" /> <item android:id="@+id/calico_menu_item" android:title="@string/calico" /> </menu> </item> </menu>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Use the constants defined in the ContextualMenus.Command enum--> <item android:id="@+id/play_menu_item" android:title="PLAY_MUSIC" /> <item android:id="@+id/pause_menu_item" android:title="PAUSE_MUSIC" /> </menu>
(Opcjonalnie) Zastąp
onPreparePanel()
, sprawdzając, czy opcjaWindowUtils.FEATURE_VOICE_COMMANDS
jest włączona. Po włączeniu tej funkcji możesz używać innych funkcji do konfigurowania systemu menu, takich jak dodawanie i usuwanie określonych pozycji menu na podstawie pewnych kryteriów. W zależności od wybranych kryteriów możesz też włączyć kontekstowe menu głosowe (powróttrue
) i wyłączenie (powrótfalse
). Przykład:private boolean mVoiceMenuEnabled; ... @Override public boolean onPreparePanel(int featureId, View view, Menu menu) { if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) { // toggle this boolean on and off based on some criteria return mVoiceMenuEnabled; } // Good practice to call through to super for other cases return super.onPreparePanel(featureId, view, menu); }
Obsługują jednocześnie menu głosu i dotyku
Kontekstowe polecenia głosowe korzystają z istniejących interfejsów API menu Androida, możesz więc ponownie wykorzystać dużą ilość kodu i zasobów, które już masz na potrzeby menu dotykowych, i jednocześnie obsługiwać oba typy menu.
Wystarczy sprawdzić funkcję Window.FEATURE_OPTIONS_PANEL
oprócz funkcji WindowUtils.FEATURE_VOICE_COMMANDS
, która jest już sprawdzana na kilka sposobów, a następnie dodać logikę, aby otworzyć menu dotykowe dla niektórych działań użytkownika, takich jak kliknięcie.
Możesz na przykład zmienić poprzednią aktywność, by dodać obsługę menu dotykowych w ten sposób (zmiany są komentowane):
// 1. Check for Window.FEATURE_OPTIONS_PANEL
// to inflate the same menu resource for touch menus.
@Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS ||
featureId == Window.FEATURE_OPTIONS_PANEL) {
...
}
// 2. Check for Window.FEATURE_OPTIONS_PANEL
// to handle touch menu item selections.
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS ||
featureId == Window.FEATURE_OPTIONS_PANEL) {
...
}
Po wprowadzeniu tych zmian możesz kliknąć lub powiedzieć OK, aby wyświetlić menu.
Korzystanie z niepublicznych poleceń głosowych na potrzeby programowania
Aby rozpowszechniać aplikację Glassware, musisz używać zatwierdzonych poleceń głównych w VoiceTriggers.Command
, a zatwierdzonych kontekstowych poleceń głosowych w ContextualMenus.Command
.
Jeśli chcesz używać poleceń głosowych niedostępnych w GDK, możesz poprosić o uprawnienia Androida w pliku AndroidManifest.xml
:
<uses-permission
android:name="com.google.android.glass.permission.DEVELOPMENT" />
Korzystanie z głównych poleceń głosowych niepublicznych
Zadeklaruj wartość ciągu znaków w
res/values/strings.xml
, która określa nazwę aktywatora głosu. Opcjonalnie przed rozpoczęciem korzystania z Google Glass zadeklaruj komunikat głosowy, by wyświetlał rozpoznawanie mowy.<?xml version="1.0" encoding="utf-8"?> <resources> <string name="glass_voice_trigger">read me a story</string> <string name="glass_voice_prompt">what story?</string> </resources>
Utwórz zasób XML dla aktywatora głosowego w:
res/xml/<my_voice_trigger>.xml
. W przypadku niewymienionych poleceń głosowych należy użyć atrybutukeyword
zamiast atrybutucommand
używanego do zatwierdzonych poleceń głosowych. Atrybutkeyword
powinien być odwołaniem do zasobu ciągu znaków definiującego polecenie głosowe. Aby użyć prostego polecenia głosowego, które rozpoczyna działanie od razu, spowoduje to określenie elementutrigger
:<?xml version="1.0" encoding="utf-8"?> <trigger keyword="@string/glass_voice_trigger" />
Aby utworzyć regułę głosową, która poprosi użytkownika o wypowiedzenie dodatkowego wyrażenia przed rozpoczęciem aktywności lub usługi, dodaj też element wprowadzania danych:
<?xml version="1.0" encoding="utf-8"?> <trigger keyword="@string/glass_voice_trigger"> <input prompt="@string/glass_voice_prompt" /> </trigger>
Używanie niepublicznych poleceń głosowych
Podczas tworzenia pozycji menu użyj dowolnego tekstu. Przykład:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Use the constants defined in the ContextualMenus.Command enum-->
<item
android:id="@+id/pizza_menu_item"
android:title="@string/find_pizza" />
</menu>
Rozpoczynam rozpoznawanie mowy
Moduł rozpoznawania mowy Google czeka, aż użytkownicy coś powiedzą, i zwróci transkrypcję tekstu, gdy skończy. Aby rozpocząć aktywność:
- Wywołaj
startActivityForResult()
z intencjąACTION_RECOGNIZE_SPEECH
. Po rozpoczęciu aktywności obsługiwane są te dodatki dodatkowe: Zastąp wywołanie zwrotne
onActivityResult()
, aby otrzymać transkrypcję tekstu z intencjiEXTRA_RESULTS
. To wywołanie zwrotne jest wywoływane, gdy użytkownik skończy mówić.private static final int SPEECH_REQUEST = 0; private void displaySpeechRecognizer() { Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); startActivityForResult(intent, SPEECH_REQUEST); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == SPEECH_REQUEST && resultCode == RESULT_OK) { List<String> results = data.getStringArrayListExtra( RecognizerIntent.EXTRA_RESULTS); String spokenText = results.get(0); // Do something with spokenText. } super.onActivityResult(requestCode, resultCode, data); }