Android Automotive uważa, że głos jest kluczowym elementem
bezpieczne dla użytkowników i jeden z najbezpieczniejszych sposobów
współdziała z systemem operacyjnym Android Automotive podczas jazdy. W związku z tym rozszerzyliśmy
Interfejsy API Asystenta głosowego na Androida (w tym VoiceInteractionSession
)
aby umożliwić asystentom głosowym wykonywanie zadań za użytkowników
co może być trudne do osiągnięcia podczas jazdy.
Dotknij, by przeczytać umożliwia asystentom głosowym czytanie SMS-ów i odpowiadanie na nie
w imieniu użytkownika, gdy wchodzi on w interakcję z powiadomieniami o wiadomościach. Aby podać
tę funkcję możesz zintegrować z asystentem głosowym
CarVoiceInteractionSession
W samochodach powiadomienia publikowane w Centrum powiadomień zostały rozpoznane
jako INBOX
lub INBOX_IN_GROUP
(np. SMS-y) zawierają
Przycisk Odtwórz. Użytkownik może kliknąć Odtwórz, aby wykonać grę
Asystent głosowy odczyta powiadomienie na głos i opcjonalnie odpowie głosowo.
Rysunek 1. Powiadomienie „Dotknij, by przeczytać” z przyciskiem odtwarzania.
Integracja z CarVoiceInteractionSession
W następnych sekcjach dowiesz się, jak zintegrować asystenta głosowego z
CarVoiceInteractionSession
Obsługa interakcji głosowych
Aplikacje oferujące w samochodzie usługi interakcji głosowej muszą
z dotychczasowymi interakcjami głosowymi na Androidzie. Więcej informacji znajdziesz w artykule o Asystencie Google na Androida.
(z wyjątkiem VoiceInteractionSession
). Chociaż wszystkie API interakcji głosowych
elementy pozostają takie same jak te zaimplementowane na urządzeniach mobilnych, CarVoiceInteractionSession
(opisane w sekcji Implementacja CarVoiceInteractionSession) zastępuje funkcja
VoiceInteractionSession
Więcej informacji znajdziesz na tych stronach:
Implementowanie CarVoiceInteractionSession
CarVoiceInteractionSession
udostępnia interfejsy API, które pozwalają asystentom głosowym odczytywać SMS-y na głos, a następnie
odpowiadać na te wiadomości w imieniu użytkownika.
Główna różnica między CarVoiceInteractionSession
a
VoiceInteractionSession
zajęcia to
CarVoiceInteractionSession
Podaje podania w onShow
aby Asystent głosowy mógł wykryć kontekst żądania użytkownika, gdy tylko
CarVoiceInteractionSession
rozpoczyna sesję. Parametry funkcji onShow
dotyczące poszczególnych zajęć podano w tej tabeli:
Sesja głosowa w samochodzie | Sesja VoiceInteraction |
---|---|
Funkcja onShow przyjmuje te 3 parametry:
|
Funkcja onShow przyjmuje te 2 parametry:
|
Zmiany w Androidzie 10
W Androidzie 10 platforma nazywa się VoiceInteractionService.onGetSupportedVoiceActions
aby wykrywać obsługiwane działania. Asystent głosowy zastępuje
implementuje dyrektywę VoiceInteractionService.onGetSupportedVoiceActions
,
jak w tym przykładzie:
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; } }
Prawidłowe działania zostały opisane w poniższej tabeli. Szczegółowe informacje o poszczególnych działaniach znajdziesz w sekcji Wykresy sekwencji.
Działanie | Oczekiwany ładunek | Oczekiwane działanie związane z interakcją głosową |
---|---|---|
VOICE_ACTION_READ_NOTIFICATION |
odczytać na głos wiadomości dla użytkownika, a następnie uruchomić polecenie „Oznacz jako przeczytane”; gdy wiadomości zostaną odczytane. Opcjonalnie uruchom użytkownika. | |
VOICE_ACTION_REPLY_NOTIFICATION |
Interfejs Parcelable z kluczem.KEY_NOTIFICATION
które wskazuje miejsce StatusBarNotification .Wymagana wartość android.permission.BIND_NOTIFICATION_LISTENER_SERVICE . |
Poproś użytkownika o podanie treści odpowiedzi i wpisanie odpowiedzi w
RemoteInputReply intencji oczekującej, a następnie uruchomić
intencję oczekującą. |
VOICE_ACTION_HANDLE_EXCEPTION |
Ciąg z kluczem.KEY_EXCEPTION .
mapujący na ExceptionValue
(opisane w sekcji Wartości wyjątków).KEY_FALLBACK_ASSISTANT_ENABLED , która jest mapowana na wartość logiczną. Jeśli wartość
to true , asystent zastępczy, który może obsłużyć żądanie użytkownika, został
wyłączono. |
Działania, jakie należy podjąć w przypadku takiego wyjątku, są określone w dokumentacji wyjątku. |
Wartości wyjątków
EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING
informuje asystenta głosowego, że nie ma uprawnienia Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE
, a następnie może uzyskać je od użytkownika.
Poproś o zgodę na detektor powiadomień
Jeśli domyślny asystent głosowy nie ma słuchacza powiadomień
FallbackAssistant
platformy
(jeśli funkcja została włączona przez producenta samochodu) może odczytać wiadomość na głos, zanim asystent głosowy
powiadomiono o konieczności prośby o przyznanie uprawnień. Aby określić, czy usługa FallbackAssistant
jest włączona i
przeczytał wiadomość, asystent głosowy powinien sprawdzić
KEY_FALLBACK_ASSISTANT_ENABLED
Wartość logiczna w ładunku.
Platforma zaleca, by asystent głosowy dodał funkcję ograniczania szybkości
ile razy poproszono o to uprawnienie. W ten sposób szanuje się użytkownik, który tego nie robi.
chcesz przyznać asystentowi głosowemu te uprawnienia i wolisz
FallbackAssistant
, aby odczytać SMS-y na głos. Prośba
użytkownik prosi o zgodę za każdym razem, gdy naciśnie Odtwórz w powiadomieniu o wiadomości
co może negatywnie wpłynąć na wrażenia użytkownika. Platforma nie nakłada limitów liczby żądań
w imieniu asystenta głosowego.
Gdy prosisz o zgodę słuchacza powiadomień, asystent głosowy powinien
użyj funkcji CarUxRestrictionsManager
, aby określić, czy użytkownik jest zaparkowany lub jedzie samochodem. Jeśli użytkownik prowadzi samochód, Asystent głosowy
wyświetla powiadomienie z instrukcjami przyznawania uprawnień. Robię to
pomaga użytkownikowi (i przypomina) zgodę na jego przyznanie, gdy jest to bezpieczniejsze.
Praca z StatusBar Notification
StatusBarNotification
zaliczyło zadanie za pomocą funkcji Czytaj i odpowiadaj
komendy głosowe są zawsze widoczne w powiadomieniu o wiadomościach zgodnych z samochodem zgodnie z opisem.
w sekcji Powiadom
wiadomości. Choć niektóre powiadomienia mogą nie mieć stanu Oczekiwanie na odpowiedź
mają intencje oczekujące na oznaczenie Oznacz jako przeczytany.
Aby usprawnić interakcję z powiadomieniami, używaj NotificationPayloadHandler
,
który pozwala wyodrębniać wiadomości z powiadomień i zapisywać
odpowiadać na wiadomości zgodne z odpowiednią intencją oczekującą. Po
asystent głosowy przeczyta wiadomość, a asystent głosowy musi uruchomić znak „Znak”
jako zamiar odczytu.
Spełnij warunki wstępne funkcji Dotknij, by przeczytać
Tylko VoiceInteractionSession
głosu domyślnego
Asystent jest powiadamiany, gdy użytkownik uruchomi komendę głosową, aby odczytać
odpowiadać na wiadomości. Jak wspomnieliśmy powyżej, ten domyślny asystent głosowy musi też
mieć uprawnienia do nasłuchiwania powiadomień.
Diagramy sekwencji
Te liczby pokazują przepływy logiczne funkcji CarVoiceInteractionSession actions
:
Rysunek 2. Schemat sekwencji dla VOICE_ACTION_READ_Powiadomienie.
W przypadku ilustracji 3 zalecamy stosowanie aplikacji limitów liczby żądań uprawnień:
Rysunek 3. Schemat sekwencji dla VOICE_ACTION_REPLY_Powiadomienie.
Rysunek 4. Schemat sekwencji: VOICE_ACTION_HANDLE_EXCEPTION.
Odczytywanie nazwy aplikacji
Jeśli chcesz, żeby asystent głosowy czytał na głos nazwę aplikacji do obsługi wiadomości podczas (np. „Jakub z Hangouts powiedział...”) utwórz funkcję podobną do tej, w poniższym przykładzie kodu, aby upewnić się, że asystent odczytuje prawidłowe imię:
@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; }