Spracheingabe

Mit der Spracheingabe können Sie die Benutzeroberfläche einfach per Sprachbefehl bedienen. In Glass haben Sie drei Möglichkeiten, die Spracheingabe zu verwenden.

Die Haupt-Sprachbefehle starten Glassware über die Karte „Startseite“. Mit kontextbezogenen Sprachbefehlen können Aktionen innerhalb einer Aktivität ausgeführt werden. Über die Spracherkennung des Systems können Sie Eingaben im freien Format von Nutzern empfangen.

Wichtigste Sprachbefehle

Mit diesen Sprachbefehlen wird Glassware über die Karte „Startseite“ (Uhr) gestartet. Wenn Sie einen Hauptbefehl per Sprachbefehl deklarieren, erstellt Glass automatisch einen Touch-Menüpunkt als Fallback, wenn Nutzer Ihre Glassware durch Tippen auf die Startseitenkarte starten möchten.

So fügen Sie dem Hauptmenü von ok Glass einen Sprachbefehl hinzu:

  1. Erstellen Sie eine XML-Ressource für den Sprachbefehl in res/xml/<my_voice_trigger>.xml, die einen der in VoiceTriggers.Command definierten vorhandenen Sprachbefehle verwendet. So können Sie beispielsweise „Ausführung starten“ verwenden.

    <?xml version="1.0" encoding="utf-8"?>
    <trigger command="START_A_RUN" />
    

    Wenn Sie einen Sprachbefehl erstellen möchten, durch den der Nutzer aufgefordert wird, eine weitere Wortgruppe zu sagen, bevor Sie Ihre Aktivität oder Ihren Dienst starten, fügen Sie auch das Element input ein. Das bietet sich beispielsweise an, wenn Sie „Update posten“ verwenden.

    <?xml version="1.0" encoding="utf-8"?>
    <trigger command="POST_AN_UPDATE">
        <input prompt="@string/glass_voice_prompt" />
    </trigger>
    
  2. Registrieren Sie einen Intent-Filter mit der Aktion com.google.android.glass.action.VOICE_TRIGGER in Ihrem Android-Manifest. Der Intent-Filter startet Ihre Aktivität oder Ihren Dienst, wenn er erkennt, dass Nutzer Ihren Sprachbefehl sprechen.

    <?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>
    
  3. Geben Sie ein android:icon-Attribut für Ihre Aktivität oder Ihren Dienst an. Dadurch kann Glass im Glass-Symbolmenü OK, Glass ein Symbol für Ihre Glassware anzeigen.

    <activity |service
        android:icon="@drawable/my_icon" ...>
      ...
    </activity | service>
    
  4. Wenn Ihr Sprachbefehl eine Sprachaufforderung verwendet und eine Aktivität startet, rufen Sie transkribierten Text mit dem folgenden Code ab (z. B. in onResume()):

    ArrayList<String> voiceResults = getIntent().getExtras()
            .getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
    

    Wenn der Sprachbefehl einen Dienst startet, ist der Intent-Zusatz im onStartCommand()-Callback verfügbar:

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        ArrayList<String> voiceResults = intent.getExtras()
                .getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
        // ...
    }
    

Einschränkungen festlegen

Wenn Sie eine oder alle der folgenden Features benötigen, um Ihre Glassware zu starten, geben Sie sie in der Ressource res/xml/<my_voice_trigger>.xml an. Wenn die Funktionen nicht verfügbar sind, deaktiviert Glass den Sprachbefehl:

  • camera
  • network
  • microphone

    <trigger command="POST_AN_UPDATE">
        <constraints
            camera="true"
            network="true" />
    </trigger>
    

Kontextbezogene Sprachbefehle

Mit kontextbezogenen Sprachbefehlen können Nutzer Aktionen aus Aktivitäten ausführen. Sie erstellen kontextbezogene Sprachbefehle mit den standardmäßigen Android-Menü-APIs. Nutzer können die Menüelemente jedoch per Sprachbefehl anstatt per Berührung aufrufen.

So aktivieren Sie kontextbezogene Sprachbefehle für eine bestimmte Aktivität:

  1. Rufe getWindow().requestFeature(WindowUtils.FEATURE_VOICE_COMMANDS) in der gewünschten Aktivität auf, um kontextbezogene Sprachbefehle zu aktivieren. Wenn diese Funktion aktiviert ist, wird das Menü "Ok Glass" in der Fußzeile des Bildschirms angezeigt, wenn diese Aktivität im Fokus ist.

  2. Überschreiben Sie onCreatePanelMenu() und bearbeiten Sie den Fall, in dem WindowUtils.FEATURE_VOICE_COMMANDS aktiviert ist. Wenn diese Option aktiviert ist, können Sie eine einmalige Menüeinrichtung vornehmen, z. B. eine Menüressource erhöhen oder die Menu.add()-Methoden aufrufen, um Ihr Sprachmenüsystem zu erstellen.

  3. Überschreiben Sie onMenuItemSelected(), um die Sprachbefehle zu verarbeiten, wenn Nutzer sie sprechen. Nachdem die Nutzer einen Menüpunkt ausgewählt haben, wird der Sprachbefehl "ok,glas" automatisch im Fußzeilenbereich des Bildschirms angezeigt. Er kann akzeptiert werden, solange die Aktivität im Fokus ist.

    Mit dem folgenden Code werden kontextbezogene Sprachbefehle aktiviert, bei Bedarf eine Menüressource aufgebläht und Sprachbefehle werden verarbeitet, wenn sie gesprochen werden:

    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);
        }
    }
    

    Hier ein Beispiel für die Menüressource, die von der vorherigen Aktivität verwendet wurde. Sie können verschachtelte Menüelemente für ein hierarchisches Sprachmenüsystem erstellen. Im folgenden Beispiel können Sie auf den ersten Menüpunkt zugreifen: 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>
    
  4. Optional: Überschreiben Sie onPreparePanel() und prüfen Sie, ob WindowUtils.FEATURE_VOICE_COMMANDS aktiviert ist. Wenn diese Option aktiviert ist, können Sie das Menüsystem auf andere Weise einrichten, z. B. bestimmte Menüpunkte basierend auf bestimmten Kriterien hinzufügen oder entfernen. Sie können die Menüs für das Kontextmenü für die Sprachsuche auch aktivieren (true zurückgeben) und deaktivieren (false zurückgeben). Beispiel:

        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);
        }
    

Unterstützte Sprach- und Touch-Menüs gleichzeitig

Da bei kontextbezogenen Sprachbefehlen die vorhandenen Android-Menü-APIs verwendet werden, können Sie einen Großteil des Codes und der Ressourcen wiederverwenden, die Sie bereits für Touch-Menüs haben, und gleichzeitig beide Arten von Menüs unterstützen.

Dazu müsst ihr nur zusätzlich zum Feature WindowUtils.FEATURE_VOICE_COMMANDS, auf das ihr bereits mit einigen Methoden nachgeschaut habt, auf das Window.FEATURE_OPTIONS_PANEL-Feature achten und dann eine Logik hinzufügen, um das Touch-Menü bei einigen Nutzeraktionen zu öffnen, z. B. durch Tippen.

Sie können beispielsweise das vorherige Aktivitätsbeispiel ändern, um Touch-Menüs wie diese hinzuzufügen (die Änderungen sind kommentiert):

// 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) {
    ...
}

Nach der Änderung kannst du entweder Ok Glass antippen oder sagen, damit dein Menü angezeigt wird.

Nicht gelistete Sprachbefehle für die Entwicklung verwenden

Wenn Sie Ihre Glassware vertreiben möchten, müssen Sie die genehmigten Hauptbefehle in VoiceTriggers.Command und genehmigte kontextbezogene Sprachbefehle in ContextualMenus.Command verwenden.

Wenn Sie Sprachbefehle verwenden möchten, die im GDK nicht verfügbar sind, können Sie in der Datei AndroidManifest.xml eine Android-Berechtigung anfordern:

<uses-permission
     android:name="com.google.android.glass.permission.DEVELOPMENT" />

Nicht gelistete Sprachbefehle verwenden

  1. Geben Sie in res/values/strings.xml einen Stringwert an, der den Namen Ihres Voice-Triggers definiert. Sie können eine Sprachaufforderung deklarieren, um die Spracherkennung von Glassware vor dem Starten anzuzeigen.

    <?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>
    
  2. Erstellen Sie in res/xml/<my_voice_trigger>.xml eine XML-Ressource für den Sprachtrigger. Für nicht aufgeführte Sprachbefehle sollten Sie das Attribut keyword anstelle des Attributs command verwenden, das für genehmigte Sprachbefehle verwendet wird. Das Attribut keyword sollte ein Verweis auf die Stringressource sein, die den Sprachbefehl definiert. Für einen einfachen Sprachbefehl, der eine Aktivität oder einen Dienst sofort startet, geben Sie einfach das Element trigger an:

    <?xml version="1.0" encoding="utf-8"?>
    <trigger keyword="@string/glass_voice_trigger" />
    

    Wenn Sie einen Sprachtrigger erstellen möchten, der den Nutzer vor Beginn der Aktivität oder des Dienstes dazu auffordert, eine weitere Wortgruppe zu sagen, fügen Sie außerdem ein Eingabeelement hinzu:

    <?xml version="1.0" encoding="utf-8"?>
    <trigger keyword="@string/glass_voice_trigger">
        <input prompt="@string/glass_voice_prompt" />
    </trigger>
    

Nicht gelistete kontextbezogene Sprachbefehle verwenden

Verwenden Sie beim Erstellen von Menüpunkten einen beliebigen Text für den Titel des Menüelements. Beispiel:

<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>

Spracherkennung wird gestartet


Die Spracherkennung wartet darauf, dass Nutzer sprechen, und gibt den transkribierten Text zurück. So starten Sie die Aktivität:

  1. Rufen Sie startActivityForResult() mit dem Intent ACTION_RECOGNIZE_SPEECH auf. Die folgenden Intent-Extras werden beim Starten der Aktivität unterstützt:
  2. Überschreiben Sie den onActivityResult()-Callback, um den transkribierten Text aus dem EXTRA_RESULTS-Intent zusätzlich zu erhalten. Dieser Callback wird aufgerufen, wenn Nutzer zu Ende sprechen.

    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);
    }