Spracheingabe

Mit der Spracheingabe können Sie eine benutzerfreundliche Oberfläche erstellen. Glass bietet drei Möglichkeiten, die Spracheingabe zu nutzen.

Haupt-Sprachbefehle starten Glassware über die Home-Karte, kontextbezogene Sprachbefehle können Aktionen innerhalb einer Aktivität ausführen und mit der Spracherkennungsaktivität des Systems können Sie Freitext-Spracheingaben von Nutzern empfangen.

Haupt-Sprachbefehle

Mit diesen Sprachbefehlen wird Glassware auf der Startseitenkarte (Uhrkarte) gestartet. Wenn Sie einen Haupt-Sprachbefehl deklarieren, erstellt Glass automatisch einen Touch-Menüpunkt als Fallback, falls Nutzer Ihre Glassware durch Tippen auf die Startseitenkarte starten möchten.

So fügen Sie dem Hauptmenü der Ok Glass-Stimme einen Sprachbefehl hinzu:

  1. Erstellen Sie eine XML-Ressource für den Sprachbefehl in res/xml/<my_voice_trigger>.xml, die einen der vorhandenen Sprachbefehle verwendet, die in VoiceTriggers.Command definiert sind. Hier siehst du zum Beispiel, wie „Starte Lauf“ verwendet wird.

    <?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, einen zusätzlichen Satz zu sagen, bevor die Aktivität oder der Dienst gestartet wird, fügen Sie auch ein input-Element ein. Das ist beispielsweise sinnvoll, wenn Sie „Aktualisierung 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 erkannt wird, dass Nutzer Ihren Sprachbefehl sagen.

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

    <activity |service
        android:icon="@drawable/my_icon" ...>
      ...
    </activity | service>
    
  4. Wenn bei Ihrem Sprachbefehl eine Aufforderung verwendet und eine Aktivität gestartet wird, rufen Sie einen 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 das Intent-Extra 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 zum Starten Ihrer Glassware eine oder alle der folgenden Funktionen benötigen, 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 in bestimmten Aktivitäten ausführen. Sie können kontextbezogene Sprachbefehle mit den standardmäßigen Menü-APIs von Android erstellen, aber Nutzer können die Menüpunkte mit Sprachbefehlen statt durch Berührung aufrufen.

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

  1. Rufen Sie 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" im Fußzeilenbereich 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, kannst du das Menü einmalig einrichten. Du kannst beispielsweise eine Menüressource aufblähen oder die Menu.add()-Methoden aufrufen, um dein Sprachmenüsystem zu erstellen.

  3. Überschreiben Sie onMenuItemSelected(), um die Sprachbefehle zu verarbeiten, die Nutzer sagen. Wenn die Nutzer einen Menüpunkt ausgewählt haben, wird der Sprachbefehl "ok, Glass" automatisch wieder im Fußzeilenbereich des Bildschirms angezeigt und kann einen neuen Sprachbefehl annehmen, solange die Aktivität im Fokus ist.

    Mit dem folgenden Code werden kontextbezogene Sprachbefehle aktiviert, eine Menüressource bei Bedarf erhöht und Sprachbefehle 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 ist ein Beispiel für die Menüressource, die in der vorherigen Aktivität verwendet wurde. Beachten Sie, wie Sie verschachtelte Menüpunkte für ein hierarchisches Sprachmenüsystem erstellen können. Im folgenden Beispiel kann auf den ersten Menüpunkt als ok Glass, Show me Dogs, Labrador zugegriffen werden.

    <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 weitere Logik zum Einrichten des Menüsystems ausführen, z. B. bestimmte Menüelemente basierend auf bestimmten Kriterien hinzufügen oder entfernen. Sie können die kontextbezogenen Sprachmenüs auch anhand bestimmter Kriterien ein- (true) und wieder deaktivieren (false) lassen. 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);
        }
    

Gleichzeitige Unterstützung von Sprach- und Touch-Menüs

Da kontextbezogene Sprachbefehle die vorhandenen Android-Menü-APIs verwenden, können Sie einen Großteil des Codes und der Ressourcen, die Sie bereits für Touch-Menüs haben, wiederverwenden und gleichzeitig beide Menütypen unterstützen.

Sie müssen nur nach der Window.FEATURE_OPTIONS_PANEL-Funktion und der WindowUtils.FEATURE_VOICE_COMMANDS-Funktion suchen, die Sie bereits in einigen Methoden geprüft haben, und dann eine Logik hinzufügen, um das Touch-Menü bei einer Nutzeraktion wie einem Tippen zu öffnen.

Sie können beispielsweise das vorherige Aktivitätsbeispiel ändern, um Touch-Menüs wie diese zu unterstützen (Änderungen werden 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 diesen Änderungen können Sie entweder auf Ok Glass tippen oder es sagen, um das Menü aufzurufen.

Nicht gelistete Sprachbefehle für die Entwicklung verwenden

Wenn Sie Glassware vertreiben möchten, müssen Sie die genehmigten Hauptsprachbefehle in VoiceTriggers.Command und genehmigte kontextabhängige Sprachbefehle in ContextualMenus.Command verwenden.

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

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

Nicht gelistete Haupt-Sprachbefehle verwenden

  1. Deklarieren Sie in res/values/strings.xml einen Stringwert, der den Namen Ihres Sprachauslösers definiert. Sie können auch eine Sprachansage angeben, um die Glassware zur Spracherkennung anzuzeigen, bevor Sie Glassware starten.

    <?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 eine XML-Ressource für den Sprachtrigger in res/xml/<my_voice_trigger>.xml. Bei nicht gelisteten Sprachbefehlen 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, mit der der Sprachbefehl definiert wird. Wenn Sie einen einfachen Sprachtrigger verwenden möchten, 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" />
    

    Um einen Sprachtrigger zu erstellen, durch den der Nutzer aufgefordert wird, einen zusätzlichen Satz zu sagen, bevor die Aktivität oder der Dienst gestartet wird, 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 Titel des Menüpunkts beliebigen Text. 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 Glassware für die Spracherkennung wartet auf das Sprechen des Nutzers und gibt den transkribierten Text zurück, wenn der Vorgang abgeschlossen ist. So starten Sie die Aktivität:

  1. Rufen Sie startActivityForResult() mit dem Intent ACTION_RECOGNIZE_SPEECH auf. Die folgenden Intent-Extras werden zu Beginn 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 der Nutzer mit dem Sprechen fertig ist.

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