Für Android Automotive ist Sprache eine wichtige Komponente für sichere Interaktionen während der Fahrt und eine der sichersten Möglichkeiten für Nutzer, während der Fahrt mit Android Automotive OS zu interagieren. Deshalb haben wir die Android-Sprachassistenten-APIs (einschließlich VoiceInteractionSession
) erweitert, damit Sprachassistenten Aufgaben für Nutzer erledigen können, die während der Fahrt schwierig zu erledigen sind.
Mit Zum Lesen tippen können Sprachassistenten Nachrichten vorlesen und beantworten, wenn der Nutzer mit Nachrichtenbenachrichtigungen interagiert. Um diese Funktion bereitzustellen, können Sie einen Sprachassistenten in CarVoiceInteractionSession
einbinden.
In der Automobilbranche enthalten Benachrichtigungen, die im Benachrichtigungscenter als INBOX
oder INBOX_IN_GROUP
gekennzeichnet sind (z. B. SMS-Nachrichten), die Schaltfläche Abspielen. Der Nutzer kann auf Abspielen klicken, um sich die Benachrichtigung vom ausgewählten Sprachassistenten vorlesen zu lassen und optional per Spracheingabe zu antworten.
Abbildung 1: Benachrichtigung mit „Zum Lesen tippen“ und Wiedergabeschaltfläche
Integration mit CarVoiceInteractionSession
In den folgenden Abschnitten wird beschrieben, wie Sie einen Sprachassistenten in CarVoiceInteractionSession
einbinden.
Sprachinteraktionen unterstützen
Apps, die Sprachinteraktionsdienste für Autos bereitstellen, müssen in die vorhandenen Android-Sprachinteraktionen eingebunden sein. Weitere Informationen finden Sie unter Google Assistant für Android (mit Ausnahme von VoiceInteractionSession
). Alle Voice Interaction API-Elemente bleiben unverändert, wie sie auf Mobilgeräten implementiert sind. CarVoiceInteractionSession
(siehe CarVoiceInteractionSession implementieren) ersetzt VoiceInteractionSession
. Weitere Informationen finden Sie auf den folgenden Seiten:
Implementieren von CarVoiceInteractionSession
CarVoiceInteractionSession
bietet APIs, mit denen Sprachassistenten SMS vorlesen und dann im Namen des Nutzers darauf antworten können.
Der Hauptunterschied zwischen den Klassen CarVoiceInteractionSession
und VoiceInteractionSession
besteht darin, dass CarVoiceInteractionSession
die Aktion in onShow
übergibt, damit der Sprachassistent den Kontext der Nutzeranfrage erkennen kann, sobald CarVoiceInteractionSession
eine Sitzung startet. Die Parameter für onShow
für jede Klasse sind in der folgenden Tabelle aufgeführt:
CarVoiceInteractionSession | VoiceInteractionSession |
---|---|
onShow hat drei Parameter:
|
onShow hat zwei Parameter:
|
Änderungen in Android 10
Ab Android 10 ruft die Plattform VoiceInteractionService.onGetSupportedVoiceActions
auf, um zu erkennen, welche Aktionen unterstützt werden. Der Sprachassistent überschreibt und implementiert VoiceInteractionService.onGetSupportedVoiceActions
, wie im folgenden Beispiel gezeigt:
public class MyInteractionService extends VoiceInteractionService { private static final ListSUPPORTED_VOICE_ACTIONS = Arrays.asList( CarVoiceInteractionSession.VOICE_ACTION_READ_NOTIFICATION); @Override public Set onGetSupportedVoiceActions(@NonNull Set voiceActions) { Set result = new HashSet<>(voiceActions); result.retainAll(SUPPORTED_VOICE_ACTIONS); return result; } }
Gültige Aktionen werden in der folgenden Tabelle beschrieben. Weitere Informationen zu den einzelnen Aktionen finden Sie unter Abfolgediagramme.
Aktion | Erwartete Nutzlast | Erwartete Sprachinteraktion |
---|---|---|
VOICE_ACTION_READ_NOTIFICATION |
Lesen Sie Nachrichten laut vor und senden Sie dann die Absicht „Als gelesen markieren (ausstehend)“ zurück, wenn die Nachrichten erfolgreich gelesen wurden. Optional können Sie den Nutzer um eine Antwort bitten. | |
VOICE_ACTION_REPLY_NOTIFICATION |
Mit Schlüssel teilbar.KEY_NOTIFICATION
wird StatusBarNotification zugeordnet.Erforderlich: android.permission.BIND_NOTIFICATION_LISTENER_SERVICE . |
Bitten Sie den Nutzer, die Antwortnachricht zu formulieren, geben Sie die Antwortnachricht in die RemoteInputReply des ausstehenden Intents ein und lösen Sie dann den ausstehenden Intent aus. |
VOICE_ACTION_HANDLE_EXCEPTION |
String mit Schlüssel.KEY_EXCEPTION , der ExceptionValue zugeordnet ist (siehe Ausnahmewerte).KEY_FALLBACK_ASSISTANT_ENABLED , der einem booleschen Wert zugeordnet ist. Wenn der Wert true ist, wurde der Fallback-Assistent, der die Anfrage des Nutzers bearbeiten kann, deaktiviert. |
Die erwartete Aktion für die Ausnahme ist in der Dokumentation für die Ausnahme definiert. |
Ausnahmewerte
EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING
weist den Sprachassistenten darauf hin, dass die Berechtigung Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE
fehlt, und dass er diese Berechtigung vom Nutzer anfordern soll.
Berechtigung für Benachrichtigungslistener anfordern
Wenn der Standard-Sprachassistent nicht die Berechtigung zum Empfangen von Benachrichtigungen hat, wird die Nachricht möglicherweise von der FallbackAssistant
der Plattform vorgelesen, bevor der Sprachassistent aufgefordert wird, die Berechtigung anzufordern (sofern vom Fahrzeughersteller aktiviert). Um festzustellen, ob FallbackAssistant
aktiviert ist und die Nachricht gelesen hat, sollte der Sprachassistent den booleschen Wert KEY_FALLBACK_ASSISTANT_ENABLED
in der Nutzlast prüfen.
Die Plattform empfiehlt, dass der Sprachassistent eine Ratenbegrenzung für die Häufigkeit der Anfrage dieser Berechtigung hinzufügt. So wird der Nutzer respektiert, der dem Sprachassistenten diese Berechtigung nicht gewähren möchte und stattdessen möchte, dass FallbackAssistant
ihm SMS vorliest. Wenn Sie Nutzer jedes Mal um Erlaubnis bitten, wenn sie bei einer Nachrichtenbenachrichtigung auf Wiedergabe tippen, kann das zu einer negativen Nutzererfahrung führen. Die Plattform erzwingt keine Ratenbegrenzungen im Namen des Sprachassistenten.
Wenn der Sprachassistent die Berechtigung zum Benachrichtigungs-Listener anfordert, sollte er CarUxRestrictionsManager
verwenden, um festzustellen, ob ein Nutzer parkt oder fährt. Wenn der Nutzer fährt, zeigt der Sprachassistent eine Benachrichtigung mit einer Anleitung zum Gewähren der Berechtigung an. So wird der Nutzer daran erinnert, die Berechtigung zu gewähren, wenn es sicherer ist.
Mit StatusBarNotification arbeiten
StatusBarNotification
, die mit den Sprachaktionen „Vorlesen“ und „Antworten“ übergeben werden, sind immer in einer fahrzeugkompatiblen Nachrichtenbenachrichtigung enthalten, wie unter Nutzer über Nachrichten informieren beschrieben. Einige Benachrichtigungen haben möglicherweise nicht den Intent „Antwort ausstehend“, aber alle haben den Intent „Als gelesen markieren ausstehend“.
Verwenden Sie NotificationPayloadHandler
, um Interaktionen mit Benachrichtigungen zu optimieren. Diese API bietet Methoden zum Extrahieren von Nachrichten aus der Benachrichtigung und zum Schreiben der Antwortnachrichten an den entsprechenden ausstehenden Intent der Benachrichtigung. Nachdem der Sprachassistent die Nachricht vorgelesen hat, muss er die Absicht „Als gelesen markieren“ auslösen.
Vorbedingungen für „Zum Lesen antippen“ erfüllen
Wenn ein Nutzer die Sprachaktion auslöst, um Nachrichten zu lesen und zu beantworten, wird nur VoiceInteractionSession
des Standard-Sprachassistenten benachrichtigt. Wie bereits erwähnt, muss dieser Standardsprachassistent auch die Berechtigung „Benachrichtigungslistener“ haben.
Sequenzdiagramme
Diese Abbildungen zeigen die Logikflüsse von CarVoiceInteractionSession actions
:
Abbildung 2: Sequenzdiagramm für VOICE_ACTION_READ_NOTIFICATION
Für Abbildung 3 wird empfohlen, die App mit Begrenzungen der Anfragehäufigkeit für Berechtigungsanfragen zu verwenden:
Abbildung 3: Sequenzdiagramm für VOICE_ACTION_REPLY_NOTIFICATION
Abbildung 4: Sequenzdiagramm für VOICE_ACTION_HANDLE_EXCEPTION
Name der App vorlesen
Wenn Ihr Sprachassistent beim Vorlesen einer Nachricht den Namen der Messaging-App vorlesen soll (z. B. „Max von Hangouts hat gesagt…“), erstellen Sie eine Funktion wie im folgenden Codebeispiel, damit der Assistent den richtigen Namen vorliest:
@Nullable String getMessageApplicationName(Context context, StatusBarNotification statusBarNotification) { ApplicationInfo info = getApplicationInfo(context, statusBarNotification.getPackageName()); if (info == null) return null; Notification notification = statusBarNotification.getNotification(); // Sometimes system packages will post on behalf of other apps, so check this // field for a system app notification. if (isSystemApp(info) && notification.extras.containsKey(Notification.EXTRA_SUBSTITUTE_APP_NAME)) { return notification.extras.getString(Notification.EXTRA_SUBSTITUTE_APP_NAME); } else { PackageManager pm = context.getPackageManager(); return String.valueOf(pm.getApplicationLabel(info)); } } @Nullable ApplicationInfo getApplicationInfo(Context context, String packageName) { final PackageManager pm = context.getPackageManager(); ApplicationInfo info; try { info = pm.getApplicationInfo(packageName, 0); } catch (PackageManager.NameNotFoundException e) { return null; } return info; } boolean isSystemApp(ApplicationInfo info) { return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; }