L'input vocale consente di creare un'interfaccia veramente in vivavoce. Glass offre tre modi per utilizzare l'input vocale.
I comandi vocali principali avviano Glassware dalla scheda Home, i comandi vocali contestuali possono eseguire azioni all'interno di un'attività e l'attività di riconoscimento vocale del sistema ti consente di ricevere input vocali in formato libero dagli utenti.
Comandi vocali principali
Questi comandi vocali avviano Glassware dalla scheda Home (scheda Orologio). Quando dichiari un comando vocale principale, Glass crea automaticamente una voce di menu touch come riserva se gli utenti decidono di avviare Glassware toccando la scheda Home.
Per aggiungere un comando vocale al menu principale vocale di ok Glass:
Crea una risorsa XML per il comando vocale in
res/xml/<my_voice_trigger>.xml
che utilizza uno dei comandi vocali esistenti definiti inVoiceTriggers.Command
. Ad esempio, ecco come utilizzare "Inizia una corsa".<?xml version="1.0" encoding="utf-8"?> <trigger command="START_A_RUN" />
Per creare un comando vocale che richieda all'utente di pronunciare una frase aggiuntiva prima di iniziare l'attività o il servizio, includi anche un elemento
input
. Ad esempio, puoi scegliere "Pubblica un aggiornamento"<?xml version="1.0" encoding="utf-8"?> <trigger command="POST_AN_UPDATE"> <input prompt="@string/glass_voice_prompt" /> </trigger>
Registra un filtro per intent utilizzando l'azione
com.google.android.glass.action.VOICE_TRIGGER
nel file manifest Android. Il filtro per intent avvia l'attività o il servizio se rileva utenti che pronunciano il comando vocale.<?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>
Dichiara un attributo
android:icon
per la tua attività o il tuo servizio. In questo modo, Glass può visualizzare un'icona per i tuoi Glassware nel menu touch ok, glass.<activity |service android:icon="@drawable/my_icon" ...> ... </activity | service>
Se il comando vocale utilizza un prompt vocale e avvia un'attività, ottieni il testo trascritto con il seguente codice (ad esempio in
onResume()
):ArrayList<String> voiceResults = getIntent().getExtras() .getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
Se il comando vocale avvia un servizio, l'intent aggiuntivo è disponibile nel callback
onStartCommand()
:@Override public int onStartCommand(Intent intent, int flags, int startId) { ArrayList<String> voiceResults = intent.getExtras() .getStringArrayList(RecognizerIntent.EXTRA_RESULTS); // ... }
Impostazione dei vincoli
Se hai bisogno di una o di tutte le seguenti funzionalità per avviare Glassware,
specificale nella risorsa res/xml/<my_voice_trigger>.xml
.
Se le funzionalità non sono disponibili, Glass disattiva il comando vocale:
camera
network
microphone
<trigger command="POST_AN_UPDATE"> <constraints camera="true" network="true" /> </trigger>
Comandi vocali contestuali
I comandi vocali contestuali consentono agli utenti di eseguire azioni dalle attività. Puoi creare comandi vocali contestuali con le API di menu Android standard, ma gli utenti possono richiamare le voci del menu con i comandi vocali anziché con il tocco.
Per attivare i comandi vocali contestuali per una determinata attività:
Chiama
getWindow().requestFeature(
WindowUtils.FEATURE_VOICE_COMMANDS
)
nell'attività che vuoi per attivare i comandi vocali contestuali. Quando questa funzionalità è attiva, ogni volta che l'attività viene impostata sullo stato attivo viene visualizzato il menu "OK Glass" nell'area del piè di pagina dello schermo.Esegui l'override di
onCreatePanelMenu()
e gestisci il caso in cuiWindowUtils.FEATURE_VOICE_COMMANDS
è abilitato. Se questa opzione è abilitata, è qui che puoi configurare il menu una tantum, ad esempio aumentare una risorsa del menu o chiamare i metodiMenu.add()
per creare il tuo sistema di menu vocale.Sostituisci
onMenuItemSelected()
per gestire i comandi vocali quando gli utenti li pronunciano. Quando gli utenti hanno finito di selezionare una voce di menu, il comando vocale "ok, vetro" viene visualizzato automaticamente nella sezione a piè di pagina dello schermo, pronto ad accettare un nuovo comando vocale, purché l'attività rimanga attiva.Il seguente codice abilita comandi vocali contestuali, gonfia una risorsa del menu quando opportuno e gestisce i comandi vocali quando vengono pronunciati:
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); } }
Ecco un esempio della risorsa di menu utilizzata dall'attività precedente. Nota come puoi creare voci di menu nidificate per un sistema di menu vocali gerarchico. Nell'esempio seguente, la prima voce di menu è accessibile come: ok glass, Show me dogs, 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>
(Facoltativo) Esegui l'override di
onPreparePanel()
, controllando seWindowUtils.FEATURE_VOICE_COMMANDS
è abilitato o meno. Se attivata, qui puoi eseguire un'altra logica per configurare il menu, ad esempio aggiungere e rimuovere determinate voci di menu in base ad alcuni criteri. Puoi anche attivare (ritornotrue
) e disattivare (ritornofalse
) i menu vocali contestuali in base ad alcuni criteri. Ad esempio: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); }
Supporto simultaneo di menu vocali e touch
Poiché i comandi vocali contestuali utilizzano le API dei menu Android esistenti, puoi riutilizzare gran parte del codice e delle risorse che già disponi per i menu touch e supportare contemporaneamente entrambi i tipi di menu.
È sufficiente controllare la funzionalità Window.FEATURE_OPTIONS_PANEL
oltre alla funzionalità WindowUtils.FEATURE_VOICE_COMMANDS
che stai già controllando
in alcuni metodi, quindi aggiungere la logica per aprire il menu touch
su alcune azioni dell'utente, ad esempio un tocco.
Ad esempio, puoi modificare l'esempio di attività precedente per aggiungere supporto per i menu touch in questo modo (le modifiche sono commenti):
// 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) {
...
}
Con queste modifiche, puoi toccare o dire ok Glass per visualizzare il tuo menu.
Utilizzo di comandi vocali non in elenco per lo sviluppo
Se vuoi distribuire i tuoi Glassware, devi utilizzare i comandi vocali principali approvati in VoiceTriggers.Command
e i comandi vocali contestuali approvati in ContextualMenus.Command
.
Se vuoi utilizzare i comandi vocali che non sono disponibili in GDK,
puoi richiedere un'autorizzazione Android nel file AndroidManifest.xml
:
<uses-permission
android:name="com.google.android.glass.permission.DEVELOPMENT" />
Utilizzare i comandi vocali principali non in elenco
Dichiara un valore stringa in
res/values/strings.xml
che definisca il nome dell'attivatore vocale. Se vuoi, puoi dichiarare un prompt vocale per visualizzare il riconoscimento vocale Glassware prima di avviare Glassware.<?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>
Crea una risorsa XML per il trigger vocale in
res/xml/<my_voice_trigger>.xml
. Per i comandi vocali non in elenco, devi utilizzare l'attributokeyword
anziché l'attributocommand
per i comandi vocali approvati. L'attributokeyword
deve essere un riferimento alla risorsa stringa che definisce il comando vocale. Per un semplice trigger vocale che avvia immediatamente un'attività o un servizio, specifica semplicemente l'elementotrigger
:<?xml version="1.0" encoding="utf-8"?> <trigger keyword="@string/glass_voice_trigger" />
Per creare un trigger vocale che richieda all'utente di pronunciare una frase aggiuntiva prima di iniziare l'attività o il servizio, includi anche un elemento di input:
<?xml version="1.0" encoding="utf-8"?> <trigger keyword="@string/glass_voice_trigger"> <input prompt="@string/glass_voice_prompt" /> </trigger>
Utilizzare i comandi vocali contestuali non in elenco
Quando crei voci di menu, utilizza qualsiasi testo per il titolo della voce. Ad esempio:
<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>
Avvio del riconoscimento vocale in corso...
Il servizio Glassware per il riconoscimento vocale attende che gli utenti parlino e restituisce il testo trascritto al termine dell'operazione. Per avviare l'attività:
- Chiamare
startActivityForResult()
con l'intentACTION_RECOGNIZE_SPEECH
. All'avvio dell'attività sono supportati i seguenti extra per intent: Esegui l'override del callback di
onActivityResult()
per ricevere il testo trascritto dall'intent extraEXTRA_RESULTS
. Questo callback viene chiamato quando gli utenti hanno finito di parlare.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); }