bibliotekę aplikacji na Androida do samochodu, umożliwia przeniesienie elementów nawigacyjnych, ciekawych miejsc (POI) i internetu rzeczy (IOT) do samochodu. Robi to, udostępniając zestaw szablonów tak, aby odwracały uwagę kierowcy. i dbania o szczegóły, takie jak różnorodność elementów na ekranie samochodu. i modalności wprowadzania.
Ten przewodnik zawiera omówienie głównych funkcji i koncepcji biblioteki przeprowadza Cię przez proces konfigurowania podstawowej aplikacji.
Zanim zaczniesz
- Zapoznaj się z artykułem Projektowanie dla kierowców
Strony obejmujące bibliotekę aplikacji samochodowych
- Aplikacje do nawigacji i inne aplikacje związane z jazdą przeglądy kategorii
- Omówienie tworzenia aplikacji przy użyciu szablonów
- Elementy składowe obejmując Szablony i komponenty Szablony.
- Przykładowe przepływy prezentacji typowych wzorców UX
- Wymagania dotyczące aplikacji utworzonych na podstawie szablonu
- Zapoznaj się z kluczowymi terminami i pojęciami w tym artykule .
- Zapoznaj się z systemem Android Auto Interfejs i system operacyjny Android Automotive projektu.
- Zapoznaj się z informacjami o wersji.
- Przejrzyj Sample.
Najważniejsze terminy i koncepcje
- Modele i szablony
- Interfejs przedstawia wykres przedstawiający obiekty modelu, które można układane razem na różne sposoby, zgodnie z szablonem, do którego należą. do. Szablony są podzbiorem modeli, które mogą stanowić podstawę wykresy. Modele zawierają informacje, które mają być wyświetlane użytkownikowi w formy tekstu i obrazów, a także atrybuty służące do konfigurowania wygląd takich informacji, np. kolory tekstu lub obrazy rozmiarów reklam Google Ads. Gospodarz przekształca modele na widoki, które mają za zadanie standardem rozpraszania uwagi kierowcy i dba o szczegóły, takie jak różnorodność czynników ekranów samochodu i opcji wprowadzania danych.
- Zorganizuj
- Host to komponent backendu, który implementuje oferowane funkcje dzięki interfejsom API biblioteki, by można było uruchamiać aplikacje w samochodzie. obowiązkiem gospodarza jest znalezienie aplikacji i zarządzanie nią, jego cyklu życia, przekształcania modeli w widoki i powiadamiania aplikacji interakcji użytkowników. Na urządzeniach mobilnych ten host jest zaimplementowany przez Androida. Autom. W systemie operacyjnym Android Automotive ten host jest instalowany jako aplikacja systemowa.
- Ograniczenia szablonów
- Różne szablony narzucają ograniczenia dotyczące treści modeli. Dla: Na przykład szablony list mają ograniczoną liczbę elementów, które można umieścić przedstawiane użytkownikowi. Szablony podlegają też ograniczeniom aby tworzyć przepływ zadania. Na przykład aplikacja może tylko przekazywać do 5 szablonów. Zobacz Więcej informacji znajdziesz w artykule Ograniczenia szablonów.
Screen
Screen
to zajęcia prowadzone przez biblioteka implementowana przez aplikacje do zarządzania interfejsem prezentowanym użytkownika.Screen
ma cykl życia i zapewnia mechanizm wysłać szablon do wyświetlenia, gdy ekran jest widoczny. Można również przekazaćScreen
instancję i przechodził do i z stosuScreen
, który zapewnia, że są one zgodne z ograniczeniach przepływu szablonów.CarAppService
CarAppService
jest abstrakcyjna klasaService
, że aplikacja musi zaimplementować i wyeksportować dane, aby były wykrywane i zarządzane przez hosta.CarAppService
w Twojej aplikacji to odpowiedzialny za weryfikację, czy połączenie z hostem jest zaufane, przy użyciucreateHostValidator
. a potem udostępniającSession
instancji dla każdego połączenia za pomocąonCreateSession
.Session
Session
jest klasą abstrakcyjną, która aplikacja musi wdrożyć i zwrócić za pomocąCarAppService.onCreateSession
Służy jako punkt wejścia do wyświetlania informacji na ekranie samochodu. it ma cykl życia, na podstawie którego bieżący stan aplikacji na ekranie samochodu, np. gdy aplikacja jest widoczne lub ukryte.Po uruchomieniu typu
Session
, na przykład przy pierwszym uruchomieniu aplikacji host prosi o pozwolenie naScreen
do wyświetlenia przy użyciuonCreateScreen
. .
Instalowanie biblioteki aplikacji w samochodzie
Zobacz bibliotekę Jetpack stronie wersji usługi instrukcje dodawania biblioteki do aplikacji.
Skonfiguruj pliki manifestu aplikacji
Zanim utworzysz aplikację samochodu, skonfiguruj jej manifestować pliki w następujący sposób.
Deklarowanie usługi CarAppService
Host łączy się z Twoją aplikacją przez
CarAppService
. Ty
zadeklaruj tę usługę w pliku manifestu, aby host mógł wykryć i nawiązać połączenie
do Twojej aplikacji.
Kategorię aplikacji musisz też zadeklarować w
<category>
elementu aplikacji
filtr intencji. Zobacz listę
obsługiwanych kategorii aplikacji w przypadku wartości dozwolonych w przypadku wartości
ten element.
Fragment kodu poniżej pokazuje, jak zadeklarować usługę aplikacji samochodowej dla punktu zainteresowanie aplikacją w pliku manifestu:
<application>
...
<service
...
android:name=".MyCarAppService"
android:exported="true">
<intent-filter>
<action android:name="androidx.car.app.CarAppService"/>
<category android:name="androidx.car.app.category.POI"/>
</intent-filter>
</service>
...
<application>
Obsługiwane kategorie aplikacji
Określ kategorię aplikacji, dodając co najmniej jedną z tych kategorii
wartości w filtrze intencji po zadeklarowaniu CarAppService
w sposób opisany
w poprzedniej sekcji:
androidx.car.app.category.NAVIGATION
: aplikacja, która udostępnia szczegółowe informacje. wskazówki dojazdu. Przeczytaj artykuł Tworzenie aplikacji do nawigacji dla samochodów. .androidx.car.app.category.POI
: aplikacja, która oferuje przydatne funkcje. do znajdowania ciekawych miejsc, takich jak miejsca parkingowe, stacje ładowania stacji paliw. Wymelduj się Tworzenie aplikacji ciekawych miejsc dla samochodów dla zapoznaj się z dodatkowymi materiałami dotyczącymi tej kategorii.androidx.car.app.category.IOT
: aplikacja, która pozwala użytkownikom podjąć odpowiednie działania na połączonych urządzeniach z poziomu samochodu. Wymelduj się Tworzenie internetu rzeczy dla samochodów zapoznaj się z dodatkowymi materiałami dotyczącymi tej kategorii.
Zobacz jakość aplikacji na Androida dla samochodów – szczegółowe opisy poszczególnych kategorii i kryteriów, według których dana aplikacja należy do nich.
Podaj nazwę i ikonę aplikacji
Musisz określić nazwę i ikonę aplikacji, których host może używać do reprezentowania Twojej w interfejsie systemowym.
Możesz podać nazwę i ikonę aplikacji, które mają służyć do jej reprezentowania.
label
oraz
icon
atrybutów
CarAppService
:
...
<service
android:name=".MyCarAppService"
android:exported="true"
android:label="@string/my_app_name"
android:icon="@drawable/my_app_icon">
...
</service>
...
Jeśli etykieta lub ikona nie są zadeklarowane w
element <service>
, host
zwraca wartości określone dla argumentu
Element <application>
.
Ustawianie motywu niestandardowego
Aby ustawić motyw niestandardowy w aplikacji samochodu, dodaj
<meta-data>
w tagu
manifestu w ten sposób:
<meta-data android:name="androidx.car.app.theme" android:resource="@style/MyCarAppTheme />
Następnie zadeklaruj zasób stylu ustaw te atrybuty niestandardowego motywu aplikacji samochodowej:
<resources> <style name="MyCarAppTheme"> <item name="carColorPrimary">@layout/my_primary_car_color</item> <item name="carColorPrimaryDark">@layout/my_primary_dark_car_color</item> <item name="carColorSecondary">@layout/my_secondary_car_color</item> <item name="carColorSecondaryDark">@layout/my_secondary_dark_car_color</item> <item name="carPermissionActivityLayout">@layout/my_custom_background</item> </style> </resources>
Poziom interfejsu API aplikacji samochodu
Biblioteka aplikacji samochodowych definiuje własne poziomy interfejsów API, dzięki czemu wiesz,
funkcje biblioteki są obsługiwane przez hosta szablonów w pojeździe.
Aby pobrać najwyższy poziom interfejsu API aplikacji samochodowej obsługiwany przez hosta, użyj
getCarAppApiLevel()
.
Zadeklaruj minimalny poziom interfejsu API aplikacji samochodowej obsługiwany przez Twoją aplikację w
Plik AndroidManifest.xml
:
<manifest ...>
<application ...>
<meta-data
android:name="androidx.car.app.minCarApiLevel"
android:value="1"/>
</application>
</manifest>
Zapoznaj się z dokumentacją:
RequiresCarApi
adnotacja ze szczegółowymi informacjami na temat zachowania zgodności wstecznej i zadeklarowania
minimalnym poziomem interfejsu API wymaganym do korzystania z danej funkcji. Definicja interfejsu API
jest wymagany, aby można było korzystać z określonej funkcji biblioteki aplikacji samochodowej, sprawdź
dokumentacja dla
CarAppApiLevels
Tworzenie usługi CarAppService i sesji
Aplikacja musi rozszerzyć
CarAppService
i zaimplementuj
jej
onCreateSession
, która zwraca Session
instancji odpowiadającej bieżącemu połączeniu z hostem:
Kotlin
class HelloWorldService : CarAppService() { ... override fun onCreateSession(): Session { return HelloWorldSession() } ... }
Java
public final class HelloWorldService extends CarAppService { ... @Override @NonNull public Session onCreateSession() { return new HelloWorldSession(); } ... }
Instancja Session
jest odpowiedzialna za
przez zwrócenie instancji Screen
, aby można było użyć
przy pierwszym uruchomieniu aplikacji:
Kotlin
class HelloWorldSession : Session() { ... override fun onCreateScreen(intent: Intent): Screen { return HelloWorldScreen(carContext) } ... }
Java
public final class HelloWorldSession extends Session { ... @Override @NonNull public Screen onCreateScreen(@NonNull Intent intent) { return new HelloWorldScreen(getCarContext()); } ... }
aby obsługiwać sytuacje, w których aplikacja samochodu musi uruchamiać się na ekranie, który nie jest
ekran główny lub ekran docelowy aplikacji, np. obsługę precyzyjnych linków,
aby wstępnie zapełnić tylny stos ekranów za pomocą
ScreenManager.push
przed powrót z
onCreateScreen
Wstępne wypełnianie umożliwia użytkownikom powrót do poprzednich ekranów
ekran aplikacji.
Tworzenie ekranu startowego
Ekrany wyświetlane przez aplikację tworzysz, definiując klasy, które rozszerzają
Screen
klasa i implementowanie jej
onGetTemplate
.
, która zwraca
Instancja Template
reprezentująca
stan interfejsu, który ma wyświetlać się na ekranie samochodu.
Fragment kodu poniżej pokazuje, jak zadeklarować parametr
Komponent typu Screen
, który korzysta z protokołu
Szablon PaneTemplate
do
wyświetl prostą wiadomość „Hello world”. ciąg znaków:
Kotlin
class HelloWorldScreen(carContext: CarContext) : Screen(carContext) { override fun onGetTemplate(): Template { val row = Row.Builder().setTitle("Hello world!").build() val pane = Pane.Builder().addRow(row).build() return PaneTemplate.Builder(pane) .setHeaderAction(Action.APP_ICON) .build() } }
Java
public class HelloWorldScreen extends Screen { @NonNull @Override public Template onGetTemplate() { Row row = new Row.Builder().setTitle("Hello world!").build(); Pane pane = new Pane.Builder().addRow(row).build(); return new PaneTemplate.Builder(pane) .setHeaderAction(Action.APP_ICON) .build(); } }
Klasa CarContext
Klasa CarContext
to
Podklasa ContextWrapper
dostępne na urządzeniach Session
i
Screen
instancji. Zapewnia dostęp
do usług samochodowych, takich jak
ScreenManager
do zarządzania:
stos ekranu;
AppManager
w przypadku ogólnych informacji o aplikacjach
funkcje, takie jak dostęp do obiektu Surface
do rysowania map;
oraz NavigationManager
wykorzystywane przez aplikacje do nawigacji zakręt po zakręcie do komunikacji nawigacji
metadane i inne
nawigacja
wydarzenia z
z serwera Google.
Patrz: Dostęp do nawigacji szablonów obszerna lista funkcji biblioteki dostępnych w aplikacjach do nawigacji.
CarContext
oferuje też inne
funkcji, takich jak wczytywanie zasobów możliwych do rysowania przy użyciu konfiguracji
na ekranie samochodu, uruchamianie w nim aplikacji za pomocą intencji,
i określanie, czy aplikacja powinna wyświetlać mapę w ciemnym motywie.
Wdróż nawigację po ekranie
Aplikacje często wyświetlają kilka różnych ekranów, z których każdy może korzystać różne szablony, które użytkownik może przeglądać podczas interakcji z nimi interfejsu wyświetlanego na ekranie.
Klasa ScreenManager
udostępnia
Stos ekranów do automatycznego otwierania ekranów
gdy użytkownik wybiera przycisk Wstecz na ekranie samochodu lub korzysta z urządzenia z tyłu.
w niektórych samochodach.
Ten fragment kodu pokazuje, jak dodać działanie wsteczne do szablonu wiadomości jako oraz czynność, która powoduje wyświetlenie nowego ekranu po wybraniu przez użytkownika:
Kotlin
val template = MessageTemplate.Builder("Hello world!") .setHeaderAction(Action.BACK) .addAction( Action.Builder() .setTitle("Next screen") .setOnClickListener { screenManager.push(NextScreen(carContext)) } .build()) .build()
Java
MessageTemplate template = new MessageTemplate.Builder("Hello world!") .setHeaderAction(Action.BACK) .addAction( new Action.Builder() .setTitle("Next screen") .setOnClickListener( () -> getScreenManager().push(new NextScreen(getCarContext()))) .build()) .build();
Obiekt Action.BACK
jest obiektem
standardowy Action
, który automatycznie
wywołuje ScreenManager.pop
.
To zachowanie można zastąpić, używając parametru
OnBackPressedDispatcher
instancji dostępnej z
CarContext
Aby można było bezpiecznie używać aplikacji podczas jazdy, stos ekranów może mieć maksymalnie dzięki głębokości 5 ekranów. Zobacz Ograniczenia dotyczące szablonów .
Odświeżanie zawartości szablonu
Aplikacja może prosić o dostęp do treści
Screen
do unieważnienia przez wywołanie metody
Metoda Screen.invalidate
.
Następnie host nawiązuje połączenie z adresem Twojej aplikacji
Screen.onGetTemplate
, aby pobrać szablon z nową zawartością.
Gdy odświeżasz Screen
,
ważne jest zrozumienie, jakie treści w szablonie można aktualizować
więc host nie wlicza nowego szablonu do limitu szablonów.
Więcej informacji znajdziesz w sekcji Ograniczenia dotyczące szablonów.
Zalecamy zorganizowanie ekranów w taki sposób, aby były one dobrze dopasowane
mapowanie między elementem Screen
a typem
który jest zwracany przez implementację onGetTemplate
.
Rysuj mapy
Aplikacje do nawigacji i ciekawych miejsc, korzystające z poniższych szablonów, mogą
rysuj mapy, korzystając z Surface
:
Szablon | Uprawnienia do szablonu | Wskazówki dotyczące kategorii |
---|---|---|
NavigationTemplate |
androidx.car.app.NAVIGATION_TEMPLATES |
Nawigacja |
MapWithContentTemplate |
androidx.car.app.NAVIGATION_TEMPLATES LUB androidx.car.app.MAP_TEMPLATES |
Nawigacja, Ważne miejsca |
MapTemplate (wycofane) |
androidx.car.app.NAVIGATION_TEMPLATES |
Nawigacja |
PlaceListNavigationTemplate (wycofane) |
androidx.car.app.NAVIGATION_TEMPLATES |
Nawigacja |
RoutePreviewNavigationTemplate (wycofane) |
androidx.car.app.NAVIGATION_TEMPLATES |
Nawigacja |
Deklarowanie uprawnień do korzystania z powierzchni
Oprócz uprawnień wymaganych w przypadku szablonu, z którego korzysta Twoja aplikacja,
aplikacja musi zadeklarować uprawnienie androidx.car.app.ACCESS_SURFACE
w swoim
AndroidManifest.xml
plik, aby uzyskać dostęp do platformy:
<manifest ...>
...
<uses-permission android:name="androidx.car.app.ACCESS_SURFACE" />
...
</manifest>
Dostęp do powierzchni
Aby uzyskać dostęp do interfejsu Surface
udostępnionego przez gospodarza, musisz zaimplementować
SurfaceCallback
i podać
tę implementację w AppManager
serwis samochodowy. Bieżąca wartość Surface
jest przekazywana do
SurfaceCallback
w parametrze SurfaceContainer
funkcji
onSurfaceAvailable()
i onSurfaceDestroyed()
wywołania zwrotne.
Kotlin
carContext.getCarService(AppManager::class.java).setSurfaceCallback(surfaceCallback)
Java
carContext.getCarService(AppManager.class).setSurfaceCallback(surfaceCallback);
Poznaj widoczny obszar powierzchni
Host może rysować elementy interfejsu dla szablonów na
mapę. Host komunikuje się na powierzchni, która ma być
nieprzesłonięte i w pełni widoczne dla użytkownika za pomocą funkcji
SurfaceCallback.onVisibleAreaChanged
. Aby zminimalizować liczbę zmian, gospodarz wywołuje metodę
SurfaceCallback.onStableAreaChanged
z najmniejszym prostokątem, który jest zawsze widoczny na podstawie argumentu
obecny szablon.
Jeśli na przykład aplikacja do nawigacji używa funkcji
NavigationTemplate
z paskiem działań u góry, można go ukryć
się, gdy użytkownik przez jakiś czas nie wchodzi w interakcję z ekranem, aby zwiększyć
miejsce na mapę. W takim przypadku jest oddzwonienie do onStableAreaChanged
i
onVisibleAreaChanged
z tym samym prostokątem. Gdy pasek działań jest ukryty,
tylko funkcja onVisibleAreaChanged
jest wywoływana z większym obszarem. Jeśli użytkownik
wejdzie w interakcję z ekranem, po czym ponownie zostanie wywołany tylko element onVisibleAreaChanged
z
pierwszego prostokąta.
Obsługa ciemnego motywu
Aplikacje muszą ponownie narysować mapę na instancji Surface
w odpowiednim kolorze ciemnego
gdy host określi odpowiednie warunki, zgodnie z opisem w
Jakość aplikacji na Androida dla samochodów.
Aby zdecydować, czy chcesz narysować ciemną mapę, możesz skorzystać z
CarContext.isDarkMode
. Po każdej zmianie stanu ciemnego motywu otrzymasz połączenie z
Session.onCarConfigurationChanged
Pozwól użytkownikom korzystać z mapy
Stosując te szablony, możesz umożliwić użytkownikom interakcję z rysowanymi mapami, dzięki czemu mogą widzieć różne części mapy, powiększania i przesuwania.
Szablon | Obsługa interaktywności od poziomu interfejsu Car App API |
---|---|
NavigationTemplate |
2 |
PlaceListNavigationTemplate (wycofane) |
4 |
RoutePreviewNavigationTemplate (wycofane) |
4 |
MapTemplate (wycofane) |
5 (wprowadzenie szablonu) |
MapWithContentTemplate |
7 (wprowadzenie szablonu) |
Wdrażanie interaktywnych wywołań zwrotnych
Interfejs SurfaceCallback
ma kilka metod wywołań zwrotnych, które można zastosować, aby dodać interaktywność do utworzonych map.
z szablonami z poprzedniej sekcji:
Interakcja | SurfaceCallback metoda |
Obsługiwane od poziomu interfejsu Car App API |
---|---|---|
Kliknij | onClick |
5 |
Ściągnij, aby powiększyć | onScale |
2 |
Przeciąganie jednym dotknięciem | onScroll |
2 |
Przesuwanie jednym kliknięciem | onFling |
2 |
Kliknij dwukrotnie | onScale (ze współczynnikiem skali określanym przez hosta szablonu) |
2 |
Posuw obrotowy w trybie przesuwania | onScroll (ze współczynnikiem odległości określanym przez hosta szablonu) |
2 |
Dodaj pasek działań na mapie
Szablony te mogą mieć pasek działań na mapie do wykonywania działań związanych z mapą, takich jak powiększanie i pomniejszanie, wyśrodkowanie, wyświetlanie kompasu i inne działania które chcesz wyświetlić. Pasek działań na mapie może mieć maksymalnie cztery przyciski z samymi ikonami które można odświeżyć bez wpływu na złożoność zadania. Ukrywa się w stanie bezczynności i pojawia się ponownie w stanie aktywności.
Aby otrzymywać interaktywne wywołania zwrotne mapy,
musi dodać przycisk Action.PAN
na pasku działań na mapie. Gdy użytkownik
naciśnie przycisk przesuwania, host przejdzie w tryb przesuwania, jak opisano w
.
Jeśli Twoja aplikacja pomija Action.PAN
na pasku działań mapy, nie otrzymuje on danych wejściowych użytkownika z
SurfaceCallback
, a host wyjdzie ze wszystkich wcześniej aktywowanych
i trybu przesuwania.
Na ekranie dotykowym przycisk przesuwania nie jest wyświetlany.
Informacje o trybie przesuwania
W trybie przesuwania host szablonu tłumaczy dane wejściowe użytkownika bez użycia dotykowego wprowadzania danych
takich jak kontrolery obrotowe i touchpady,
SurfaceCallback
metody. Reaguje na działanie użytkownika, które powoduje przejście do trybu przesuwania lub zamykanie tego trybu
z
setPanModeListener
w NavigationTemplate.Builder
. Host może ukryć inny interfejs
w szablonie, gdy użytkownik jest w trybie przesuwania.
Interakcja z użytkownikiem
Aplikacja może wchodzić w interakcję z użytkownikiem za pomocą wzorców podobnych do aplikacji mobilnej.
Obsługa danych wejściowych użytkownika
Aplikacja może reagować na dane wejściowe użytkownika, przekazując odpowiednie detektory do funkcji
które je wspierają. Fragment kodu poniżej pokazuje, jak utworzyć
Action
model, który ustawia
OnClickListener
, które
wywołuje metodę zdefiniowaną w kodzie aplikacji:
Kotlin
val action = Action.Builder() .setTitle("Navigate") .setOnClickListener(::onClickNavigate) .build()
Java
Action action = new Action.Builder() .setTitle("Navigate") .setOnClickListener(this::onClickNavigate) .build();
Metoda onClickNavigate
może wtedy uruchomić metodę
domyślna aplikacja do nawigacji
za pomocą funkcji
CarContext.startCarApp
:
Kotlin
private fun onClickNavigate() { val intent = Intent(CarContext.ACTION_NAVIGATE, Uri.parse("geo:0,0?q=" + address)) carContext.startCarApp(intent) }
Java
private void onClickNavigate() { Intent intent = new Intent(CarContext.ACTION_NAVIGATE, Uri.parse("geo:0,0?q=" + address)); getCarContext().startCarApp(intent); }
Więcej informacji o uruchamianiu aplikacji, w tym o formacie
intencja ACTION_NAVIGATE
, zobacz Uruchamianie aplikacji samochodowej z intencją
.
Niektóre działania, na przykład te, które wymagają poinstruowania użytkownika, aby kontynuował
interakcji na urządzeniach mobilnych, są dozwolone tylko wtedy, gdy zaparkowany samochód jest zaparkowany.
Za pomocą
ParkedOnlyOnClickListener
do wdrożenia tych działań. Jeśli samochód nie jest zaparkowany, gospodarz wyświetla komunikat
aby poinformować użytkownika, że dane działanie jest w danym przypadku niedozwolone. Jeśli samochód
jest zaparkowany, kod jest wykonywany normalnie. Ten fragment kodu pokazuje, jak
użyj funkcji ParkedOnlyOnClickListener
Aby otworzyć ekran ustawień na urządzeniu mobilnym:
Kotlin
val row = Row.Builder() .setTitle("Open Settings") .setOnClickListener(ParkedOnlyOnClickListener.create(::openSettingsOnPhone)) .build()
Java
Row row = new Row.Builder() .setTitle("Open Settings") .setOnClickListener(ParkedOnlyOnClickListener.create(this::openSettingsOnPhone)) .build();
Wyświetlanie powiadomień
Powiadomienia wysyłane na urządzenie mobilne wyświetlają się na ekranie samochodu tylko wtedy, gdy
są rozszerzone o
CarAppExtender
Niektóre atrybuty powiadomień, takie jak tytuł treści, tekst, ikona i działania,
można ustawić w CarAppExtender
, zastępując atrybuty powiadomienia
gdy pojawią się na ekranie samochodu.
Ten fragment kodu pokazuje, jak wysłać powiadomienie na ekran samochodu, który zawiera inny tytuł niż na urządzeniu mobilnym:
Kotlin
val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) .setContentTitle(titleOnThePhone) .extend( CarAppExtender.Builder() .setContentTitle(titleOnTheCar) ... .build()) .build()
Java
Notification notification = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) .setContentTitle(titleOnThePhone) .extend( new CarAppExtender.Builder() .setContentTitle(titleOnTheCar) ... .build()) .build();
Powiadomienia mogą wpływać na te części interfejsu użytkownika:
- Użytkownikowi może zostać wyświetlone powiadomienie HUD.
- W centrum powiadomień można dodać wpis, opcjonalnie z plakietką widoczne na szynie.
- W przypadku aplikacji nawigacyjnych powiadomienie może być wyświetlane w widżecie kolei jako opisane w Powiadomienia zakręt po zakręcie
Możesz wybrać, jak chcesz skonfigurować powiadomienia aplikacji, aby wpływały na każde z
tych elementów interfejsu przy użyciu priorytetu powiadomienia, zgodnie z opisem.
w
CarAppExtender
dokumentacji.
Jeśli
NotificationCompat.Builder.setOnlyAlertOnce
jest wywoływane z wartością true
, powiadomienie o wysokim priorytecie jest wyświetlane jako
HUN tylko raz.
Więcej informacji o projektowaniu powiadomień w aplikacji w samochodzie znajdziesz w Przewodnik Google Design for Automotive – informacje Powiadomienia.
Wyświetlaj powiadomienia
Aplikacja może wyświetlać toast za pomocą
CarToast
jak w tym fragmencie:
Kotlin
CarToast.makeText(carContext, "Hello!", CarToast.LENGTH_SHORT).show()
Java
CarToast.makeText(getCarContext(), "Hello!", CarToast.LENGTH_SHORT).show();
Poproś o uprawnienia
Jeśli aplikacja wymaga dostępu do danych lub działań objętych ograniczeniami, na przykład
lokalizacja – standardowe reguły Androida,
uprawnienia
zastosuj. Aby poprosić o przyznanie uprawnień, możesz użyć
CarContext.requestPermissions()
.
Zaletą stosowania
CarContext.requestPermissions()
, w przeciwieństwie do używania
standardowych interfejsów API Androida.
i nie musisz uruchamiać
własnego rozwiązania Activity
utworzyć okno uprawnień. Ponadto możesz używać tego samego kodu w obu
Android Auto i Android Automotive – bez konieczności tworzenia
i zależą od platformy.
Określanie stylu okna uprawnień w Androidzie Auto
W Androidzie Auto na telefonie pojawi się okno uprawnień użytkownika.
Domyślnie okno dialogowe nie jest umieszczone w żadnym tle. Aby ustawić własny
Tło, zadeklaruj motyw aplikacji samochodowej
AndroidManifest.xml
i ustaw atrybut carPermissionActivityLayout
do motywu aplikacji samochodu.
<meta-data android:name="androidx.car.app.theme" android:resource="@style/MyCarAppTheme />
Następnie ustaw atrybut carPermissionActivityLayout
dla motywu aplikacji samochodowej:
<resources> <style name="MyCarAppTheme"> <item name="carPermissionActivityLayout">@layout/my_custom_background</item> </style> </resources>
Uruchamianie aplikacji samochodowej z zamiarem
Możesz wywołać funkcję
CarContext.startCarApp
możesz wykonać jedną z tych czynności:
- Aby zadzwonić, otwórz aplikację telefonu.
- Rozpocznij szczegółową nawigację do lokalizacji za pomocą domyślna aplikacja do nawigacji.
- Uruchom własną aplikację z intencją.
Przykład poniżej pokazuje, jak utworzyć powiadomienie z działaniem,
otwiera aplikację na ekranie ze szczegółami rezerwacji parkingu.
Rozszerzasz instancję powiadomienia o intencję dotyczącą treści, która zawiera
PendingIntent
Opakowywanie elementu dla pełnoletnich
zamiar związany z działaniem Twojej aplikacji:
Kotlin
val notification = notificationBuilder ... .extend( CarAppExtender.Builder() .setContentIntent( PendingIntent.getBroadcast( context, ACTION_VIEW_PARKING_RESERVATION.hashCode(), Intent(ACTION_VIEW_PARKING_RESERVATION) .setComponent(ComponentName(context, MyNotificationReceiver::class.java)), 0)) .build())
Java
Notification notification = notificationBuilder ... .extend( new CarAppExtender.Builder() .setContentIntent( PendingIntent.getBroadcast( context, ACTION_VIEW_PARKING_RESERVATION.hashCode(), new Intent(ACTION_VIEW_PARKING_RESERVATION) .setComponent(new ComponentName(context, MyNotificationReceiver.class)), 0)) .build());
Aplikacja musi również zadeklarować
BroadcastReceiver
, czyli
wywołana w celu przetworzenia intencji, gdy użytkownik wybierze działanie w
interfejsu powiadomień i wywołuje
CarContext.startCarApp
z intencją zawierającą identyfikator URI danych:
Kotlin
class MyNotificationReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val intentAction = intent.action if (ACTION_VIEW_PARKING_RESERVATION == intentAction) { CarContext.startCarApp( intent, Intent(Intent.ACTION_VIEW) .setComponent(ComponentName(context, MyCarAppService::class.java)) .setData(Uri.fromParts(MY_URI_SCHEME, MY_URI_HOST, intentAction))) } } }
Java
public class MyNotificationReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String intentAction = intent.getAction(); if (ACTION_VIEW_PARKING_RESERVATION.equals(intentAction)) { CarContext.startCarApp( intent, new Intent(Intent.ACTION_VIEW) .setComponent(new ComponentName(context, MyCarAppService.class)) .setData(Uri.fromParts(MY_URI_SCHEME, MY_URI_HOST, intentAction))); } } }
Pamiętaj też, że
Session.onNewIntent
w aplikacji obsługuje tę intencję, przesuwając ekran rezerwacji parkingu.
w ramach stosu, jeśli jeszcze nie ma go na górze:
Kotlin
override fun onNewIntent(intent: Intent) { val screenManager = carContext.getCarService(ScreenManager::class.java) val uri = intent.data if (uri != null && MY_URI_SCHEME == uri.scheme && MY_URI_HOST == uri.schemeSpecificPart && ACTION_VIEW_PARKING_RESERVATION == uri.fragment ) { val top = screenManager.top if (top !is ParkingReservationScreen) { screenManager.push(ParkingReservationScreen(carContext)) } } }
Java
@Override public void onNewIntent(@NonNull Intent intent) { ScreenManager screenManager = getCarContext().getCarService(ScreenManager.class); Uri uri = intent.getData(); if (uri != null && MY_URI_SCHEME.equals(uri.getScheme()) && MY_URI_HOST.equals(uri.getSchemeSpecificPart()) && ACTION_VIEW_PARKING_RESERVATION.equals(uri.getFragment()) ) { Screen top = screenManager.getTop(); if (!(top instanceof ParkingReservationScreen)) { screenManager.push(new ParkingReservationScreen(getCarContext())); } } }
Więcej informacji znajdziesz w sekcji Wyświetlanie powiadomień. o tym, jak obsługiwać powiadomienia z aplikacji samochodu.
Ograniczenia szablonów
Host ogranicza liczbę szablonów, które mogą być wyświetlane dla danego zadania z pięciu, z których ostatni szablon musi być jednym z tych typów:
Pamiętaj, że limit ten dotyczy liczby szablonów, a nie liczby szablonów
Screen
instancji w stosie. Dla:
Jeśli na przykład aplikacja wysyła 2 szablony na ekranie A, a następnie przesyła ekran
B, można wysłać 3 kolejne szablony. Innym sposobem, jeśli każdy ekran jest
jeden szablon, aplikacja może przekazać pięć wystąpień ekranu
Stos ScreenManager
.
Istnieją szczególne okoliczności dotyczące tych ograniczeń: odświeżanie szablonów, cofanie się i operacji resetowania.
Odświeżanie szablonów
Niektóre aktualizacje treści nie są wliczane do limitu szablonów. Ogólnie rzecz biorąc,
jeśli aplikacja przekazuje nowy szablon tego samego typu i zawiera
zawiera tę samą główną zawartość co poprzedni, nowy szablon nie jest
wliczane do limitu. Na przykład zaktualizowanie stanu przełączania wiersza w
ListTemplate
nie liczy się
w ramach limitu. Więcej informacji znajdziesz w dokumentacji poszczególnych szablonów
o typach aktualizacji treści, które można uznać za odświeżenie.
Operacje wsteczne
Aby włączyć przepływy podrzędne w zadaniu, host wykrywa, kiedy aplikacja wyświetla
Screen
ze stosu ScreenManager
i aktualizacje
pozostały limit na podstawie liczby szablonów używanych przez aplikację
do tyłu o.
Jeśli na przykład aplikacja wysyła 2 szablony na ekranie A, a następnie przekazuje ekranu B i wyśle 2 kolejne szablony, aplikacji pozostanie 1 limit. Jeśli aplikacja wraca do ekranu A, host resetuje limit do trzech, ponieważ aplikacja została cofnięta o 2 szablony.
Pamiętaj, że po powrocie na ekran aplikacja musi wysłać szablon, który jest tego samego typu co ostatnio wysłane przez ten ekran. Wysyłam inne powoduje błąd. Dopóki jednak ten typ pozostanie tak samo podczas operacji cofania, aplikacja może dowolnie modyfikować zawartość bez wpływu na limit.
Zresetuj operacje
Niektóre szablony mają specjalną semantykę, która wskazuje zakończenie danego zadania. Dla:
Na przykład
NavigationTemplate
jest wyświetlany na ekranie i odświeżany
szczegółowe instrukcje dotyczące tego, co
umieścić w aplikacji. Gdy dotrze do któregoś z tych
host zresetuje limit szablonu, traktując ten szablon tak, jakby
To pierwszy krok nowego zadania. Dzięki temu aplikacja będzie mogła rozpocząć nowe zadanie.
Aby sprawdzić, które z nich uruchamiają resetowanie, zapoznaj się z dokumentacją poszczególnych szablonów
na hoście.
jeśli host otrzymuje intencję uruchomienia aplikacji w wyniku działania powiadomienia lub z Menu z aplikacjami limit też zostanie zresetowany. Dzięki temu mechanizmowi rozpoczyna nowy przepływ zadań z powiadomień i obowiązuje nawet wtedy, gdy aplikacja i znajdują się na pierwszym planie.
Więcej informacji znajdziesz w sekcji Wyświetlanie powiadomień. jak wyświetlać powiadomienia z aplikacji na ekranie samochodu. Zobacz W sekcji Uruchamianie aplikacji samochodowej z intencją dowiesz się, jak to zrobić. , aby uruchomić aplikację z poziomu powiadomienia.
Interfejs Connection API
Możesz sprawdzić, czy aplikacja działa na Androidzie Auto czy na Androidzie
Automotive OS przy użyciu
CarConnection
API do
pobierania informacji o połączeniu w czasie działania.
Na przykład w Session
aplikacji samochodu zainicjuj CarConnection
i
subskrybuj aktualizacje kanału LiveData
:
Kotlin
CarConnection(carContext).type.observe(this, ::onConnectionStateUpdated)
Java
new CarConnection(getCarContext()).getType().observe(this, this::onConnectionStateUpdated);
Można w nim reagować na zmiany stanu połączenia:
Kotlin
fun onConnectionStateUpdated(connectionState: Int) { val message = when(connectionState) { CarConnection.CONNECTION_TYPE_NOT_CONNECTED -> "Not connected to a head unit" CarConnection.CONNECTION_TYPE_NATIVE -> "Connected to Android Automotive OS" CarConnection.CONNECTION_TYPE_PROJECTION -> "Connected to Android Auto" else -> "Unknown car connection type" } CarToast.makeText(carContext, message, CarToast.LENGTH_SHORT).show() }
Java
private void onConnectionStateUpdated(int connectionState) { String message; switch(connectionState) { case CarConnection.CONNECTION_TYPE_NOT_CONNECTED: message = "Not connected to a head unit"; break; case CarConnection.CONNECTION_TYPE_NATIVE: message = "Connected to Android Automotive OS"; break; case CarConnection.CONNECTION_TYPE_PROJECTION: message = "Connected to Android Auto"; break; default: message = "Unknown car connection type"; break; } CarToast.makeText(getCarContext(), message, CarToast.LENGTH_SHORT).show(); }
Interfejs API ograniczeń
Różne samochody mogą pozwalać na różną liczbę
Item
instancji do wyświetlenia
jednego użytkownika. Użyj
ConstraintManager
by sprawdzić limit treści w czasie działania i ustawić odpowiednią liczbę elementów
w szablonach.
Zacznij od pobrania ConstraintManager
z CarContext
:
Kotlin
val manager = carContext.getCarService(ConstraintManager::class.java)
Java
ConstraintManager manager = getCarContext().getCarService(ConstraintManager.class);
Następnie możesz przesłać zapytanie do pobranego obiektu ConstraintManager
, aby znaleźć odpowiednie
limitu treści. Aby na przykład uzyskać liczbę produktów, które można wyświetlić
siatka, wywołanie
getContentLimit
z
CONTENT_LIMIT_TYPE_GRID
:
Kotlin
val gridItemLimit = manager.getContentLimit(ConstraintManager.CONTENT_LIMIT_TYPE_GRID)
Java
int gridItemLimit = manager.getContentLimit(ConstraintManager.CONTENT_LIMIT_TYPE_GRID);
Dodaj proces logowania
Jeśli aplikacja umożliwia logowanie się użytkownikom, możesz użyć takich szablonów jak
SignInTemplate
i LongMessageTemplate
używając interfejsu Car App API poziomu 2 lub nowszego, aby obsługiwać logowanie się w aplikacji
w konsoli centralnej samochodu.
Aby utworzyć SignInTemplate
, zdefiniuj SignInMethod
. Samochód
Biblioteka aplikacji obsługuje obecnie te metody logowania:
InputSignInMethod
logowania przy użyciu nazwy użytkownika/hasła.PinSignInMethod
logowania się przy użyciu kodu PIN, czyli połączenie konta za pomocą telefonu za pomocą kodu PIN wyświetlanego na radioodtwarzaczu.ProviderSignInMethod
na potrzeby logowania się przez dostawcę, Logowanie przez Google i Jedno dotknięcie.QRCodeSignInMethod
w przypadku logowania za pomocą kodu QR – użytkownik skanuje ten kod, aby dokończyć logowanie swój telefon. Ta funkcja jest dostępna w przypadku interfejsu Car API na poziomie 4 lub wyższym.
Aby na przykład wdrożyć szablon, który zbiera hasło użytkownika, zacznij od
tworzenie InputCallback
do przetwarzania i weryfikowania danych wejściowych użytkownika:
Kotlin
val callback = object : InputCallback { override fun onInputSubmitted(text: String) { // You will receive this callback when the user presses Enter on the keyboard. } override fun onInputTextChanged(text: String) { // You will receive this callback as the user is typing. The update // frequency is determined by the host. } }
Java
InputCallback callback = new InputCallback() { @Override public void onInputSubmitted(@NonNull String text) { // You will receive this callback when the user presses Enter on the keyboard. } @Override public void onInputTextChanged(@NonNull String text) { // You will receive this callback as the user is typing. The update // frequency is determined by the host. } };
InputSignInMethod
Builder
wymaga podania wartości InputCallback
.
Kotlin
val passwordInput = InputSignInMethod.Builder(callback) .setHint("Password") .setInputType(InputSignInMethod.INPUT_TYPE_PASSWORD) ... .build()
Java
InputSignInMethod passwordInput = new InputSignInMethod.Builder(callback) .setHint("Password") .setInputType(InputSignInMethod.INPUT_TYPE_PASSWORD) ... .build();
Na koniec użyj nowego urządzenia InputSignInMethod
, aby utworzyć SignInTemplate
.
Kotlin
SignInTemplate.Builder(passwordInput) .setTitle("Sign in with username and password") .setInstructions("Enter your password") .setHeaderAction(Action.BACK) ... .build()
Java
new SignInTemplate.Builder(passwordInput) .setTitle("Sign in with username and password") .setInstructions("Enter your password") .setHeaderAction(Action.BACK) ... .build();
Użyj usługi AccountManager
Aplikacje na system operacyjny Android Automotive, które wymagają uwierzytelniania, muszą używać AccountManager – możliwe przyczyny:
- Lepsze wrażenia użytkowników i łatwiejsze zarządzanie kontem: użytkownicy mogą łatwo zarządzać wszystkimi w menu kont w ustawieniach systemowych, w tym na stronie logowania i wylogować się.
- „Gość” : samochody są współużytkowanymi urządzeniami, więc producenci OEM mogą usług dla gości, w przypadku których nie można dodawać kont.
Dodaj warianty ciągu tekstowego
Ilość tekstu może się różnić w zależności od rozmiaru ekranu samochodu. Z interfejsem Car App API
na poziomie 2 i wyższym, możesz określić wiele wariantów ciągu tekstowego,
dopasowują się do ekranu. Aby sprawdzić, gdzie akceptowane są warianty tekstu, poszukaj szablonów
komponenty, które przyjmują CarText
.
Do elementu CarText
możesz dodać warianty ciągu tekstowego,
CarText.Builder.addVariant()
.
:
Kotlin
val itemTitle = CarText.Builder("This is a very long string") .addVariant("Shorter string") ... .build()
Java
CarText itemTitle = new CarText.Builder("This is a very long string") .addVariant("Shorter string") ... .build();
Następnie możesz użyć tego atrybutu CarText
jako głównego tekstu w
GridItem
Kotlin
GridItem.Builder() .addTitle(itemTitle) ... .build()
Java
new GridItem.Builder() .addTitle(itemTitle) ... build();
Dodaj ciągi znaków w kolejności od największej do najmniej preferowanej, na przykład od najdłuższego do najdłuższego najkrótszy. Gospodarz wybiera ciąg o odpowiedniej długości w zależności od tagu ilość miejsca dostępnego na ekranie samochodu.
Dodaj wbudowane CarIcon dla wierszy
Możesz dodać ikony w tekście, aby zwiększyć atrakcyjność aplikacji za pomocą:
CarIconSpan
Zobacz dokumentację:
CarIconSpan.create
, aby dowiedzieć się więcej o tworzeniu tych spanów. Zobacz
Świetne
stylu tekstu za pomocą Spansów, aby dowiedzieć się, jak działają style tekstu ze spanami.
Kotlin
val rating = SpannableString("Rating: 4.5 stars") rating.setSpan( CarIconSpan.create( // Create a CarIcon with an image of four and a half stars CarIcon.Builder(...).build(), // Align the CarIcon to the baseline of the text CarIconSpan.ALIGN_BASELINE ), // The start index of the span (index of the character '4') 8, // The end index of the span (index of the last 's' in "stars") 16, Spanned.SPAN_INCLUSIVE_INCLUSIVE ) val row = Row.Builder() ... .addText(rating) .build()
Java
SpannableString rating = new SpannableString("Rating: 4.5 stars"); rating.setSpan( CarIconSpan.create( // Create a CarIcon with an image of four and a half stars new CarIcon.Builder(...).build(), // Align the CarIcon to the baseline of the text CarIconSpan.ALIGN_BASELINE ), // The start index of the span (index of the character '4') 8, // The end index of the span (index of the last 's' in "stars") 16, Spanned.SPAN_INCLUSIVE_INCLUSIVE ); Row row = new Row.Builder() ... .addText(rating) .build();
Interfejsy API do sprzętu samochodowego
Począwszy od interfejsu Car App API poziomu 3, biblioteka aplikacji w samochodzie zawiera interfejsy API, których może używać, aby uzyskać dostęp do właściwości i czujników pojazdu.
Wymagania
Aby używać interfejsów API z Androidem Auto, zacznij od dodania zależności
androidx.car.app:app-projected
do pliku build.gradle
na Androida
Moduł automatyczny. W przypadku systemu operacyjnego Android Automotive dodaj zależność:
androidx.car.app:app-automotive
do pliku build.gradle
na Androida
Moduł systemu operacyjnego samochodu.
Dodatkowo w pliku AndroidManifest.xml
musisz:
zadeklarować odpowiednie uprawnienia niezbędne do tego,
żądania danych o samochodzie, których chcesz użyć. Pamiętaj, że te uprawnienia muszą być też
przyznany przez użytkownika. Za pomocą
ten sam kod w systemie operacyjnym Android Auto i Android Automotive, a nie
niż tworzenie przepływów zależnych od platformy. Jednak wymagane uprawnienia
różnią się od siebie.
Informacje o samochodzie
W tej tabeli opisano właściwości wywoływane przez
Interfejsy API CarInfo
oraz
uprawnienia, jakie musisz uzyskać, aby z nich korzystać:
Metody | Właściwości | Uprawnienia Androida Auto | Uprawnienia systemu operacyjnego Android Automotive | Obsługiwane od poziomu interfejsu Car App API |
---|---|---|---|---|
fetchModel |
Marka, model, rok | android.car.permission.CAR_INFO |
3 | |
fetchEnergyProfile |
Typy złączy EV, paliwa | com.google.android.gms.permission.CAR_FUEL |
android.car.permission.CAR_INFO |
3 |
fetchExteriorDimensions
Te dane są dostępne tylko w niektórych pojazdach z systemem operacyjnym Android Automotive z uruchomionym interfejsem API w wersji 30 lub nowszej, . |
Wymiary zewnętrzne | Nie dotyczy | android.car.permission.CAR_INFO |
7 |
addTollListener
removeTollListener |
Stan karty płatnej, typ karty płatnej | 3 | ||
addEnergyLevelListener
removeEnergyLevelListener |
Poziom baterii, poziom paliwa, niski poziom paliwa, pozostały zasięg | com.google.android.gms.permission.CAR_FUEL |
android.car.permission.CAR_ENERGY ,android.car.permission.CAR_ENERGY_PORTS ,android.car.permission.READ_CAR_DISPLAY_UNITS
|
3 |
addSpeedListener
removeSpeedListener |
Prędkość ogólna, wyświetlanie (widoczne na wyświetlaczu w samochodzie) | com.google.android.gms.permission.CAR_SPEED |
android.car.permission.CAR_SPEED ,android.car.permission.READ_CAR_DISPLAY_UNITS |
3 |
addMileageListener
removeMileageListener |
Drogomierz | com.google.android.gms.permission.CAR_MILEAGE |
Te dane nie są dostępne w systemie operacyjnym Android Automotive w przypadku aplikacji zainstalowanych ze Sklepu Play. | 3 |
Aby na przykład uzyskać pozostały zakres, utwórz wystąpienie
CarInfo
obiekt, a potem
utwórz i zarejestruj OnCarDataAvailableListener
:
Kotlin
val carInfo = carContext.getCarService(CarHardwareManager::class.java).carInfo val listener = OnCarDataAvailableListener<EnergyLevel> { data -> if (data.rangeRemainingMeters.status == CarValue.STATUS_SUCCESS) { val rangeRemaining = data.rangeRemainingMeters.value } else { // Handle error } } carInfo.addEnergyLevelListener(carContext.mainExecutor, listener) … // Unregister the listener when you no longer need updates carInfo.removeEnergyLevelListener(listener)
Java
CarInfo carInfo = getCarContext().getCarService(CarHardwareManager.class).getCarInfo(); OnCarDataAvailableListener<EnergyLevel> listener = (data) -> { if(data.getRangeRemainingMeters().getStatus() == CarValue.STATUS_SUCCESS) { float rangeRemaining = data.getRangeRemainingMeters().getValue(); } else { // Handle error } }; carInfo.addEnergyLevelListener(getCarContext().getMainExecutor(), listener); … // Unregister the listener when you no longer need updates carInfo.removeEnergyLevelListener(listener);
Nie zakładaj, że dane z samochodu są dostępne przez cały czas.
Jeśli pojawi się błąd, sprawdź
stan
wartość, która pozwoli Ci lepiej zrozumieć, dlaczego dane, których dotyczy prośba,
nie mogą zostać pobrane. Zapoznaj się z
dokumentacji referencyjnej dotyczącej
pełną definicję klasy CarInfo
.
Czujniki samochodów
Zajęcia CarSensors
umożliwia dostęp do akcelerometru, żyroskopu, kompasu i
dane o lokalizacji. Dostępność tych wartości może zależeć od
OEM. Format danych z akcelerometru, żyroskopu i kompasu to
taka sama jak w przypadku strony
SensorManager
API. Przykład:
aby sprawdzić kierunek pojazdu:
Kotlin
val carSensors = carContext.getCarService(CarHardwareManager::class.java).carSensors val listener = OnCarDataAvailableListener<Compass> { data -> if (data.orientations.status == CarValue.STATUS_SUCCESS) { val orientation = data.orientations.value } else { // Data not available, handle error } } carSensors.addCompassListener(CarSensors.UPDATE_RATE_NORMAL, carContext.mainExecutor, listener) … // Unregister the listener when you no longer need updates carSensors.removeCompassListener(listener)
Java
CarSensors carSensors = getCarContext().getCarService(CarHardwareManager.class).getCarSensors(); OnCarDataAvailableListener<Compass> listener = (data) -> { if (data.getOrientations().getStatus() == CarValue.STATUS_SUCCESS) { List<Float> orientations = data.getOrientations().getValue(); } else { // Data not available, handle error } }; carSensors.addCompassListener(CarSensors.UPDATE_RATE_NORMAL, getCarContext().getMainExecutor(), listener); … // Unregister the listener when you no longer need updates carSensors.removeCompassListener(listener);
Aby uzyskać dostęp do danych o lokalizacji samochodu, musisz też zadeklarować
Uprawnienie android.permission.ACCESS_FINE_LOCATION
.
Testowanie
Aby symulować dane z czujnika podczas testowania na Androidzie Auto, zapoznaj się z artykułem Czujniki i Czujniki konfiguracji sekcji Przewodnik po biurkowej jednostce centralnej. Aby symulować dane z czujników podczas testowania na Androidzie Automotive OS, zapoznaj się z artykułem na temat emulacji sprzętu stanu w Androidzie Przewodnik po emulatorze systemu operacyjnego Automotive.
Cykle życia usług CarAppService, sesji i ekranu
Session
oraz
Klasy Screen
stosują
Interfejs LifecycleOwner
. Jako
gdy użytkownik wchodzi w interakcję z aplikacją oraz obiektami Session
i Screen
cykl życia
wywołania zwrotne są wywoływane w sposób opisany na diagramach poniżej.
Cykle życia sesji CarAppService i sesji
Szczegółowe informacje znajdziesz w dokumentacji
Session.getLifecycle
.
Cykl życia ekranu
Szczegółowe informacje znajdziesz w dokumentacji
Screen.getLifecycle
.
Nagrywaj z mikrofonu w samochodzie
Użycie
CarAppService
oraz
CarAudioRecord
API,
możesz zezwolić aplikacji na dostęp do mikrofonu w samochodzie użytkownika. Użytkownicy muszą przekazać
aplikacji na dostęp do mikrofonu w samochodzie. Aplikacja może nagrywać
przetwarzania danych wejściowych użytkownika w aplikacji.
Uprawnienia do nagrywania
Przed rozpoczęciem nagrywania dźwięku należy zadeklarować uprawnienia do nagrywania na
AndroidManifest.xml
i poproś użytkownika o jego przyznanie.
<manifest ...>
...
<uses-permission android:name="android.permission.RECORD_AUDIO" />
...
</manifest>
Musisz poprosić o uprawnienia do nagrywania w czasie działania. Zobacz wniosek uprawnień, gdzie dowiesz się, jak poprosić o aplikacji w samochodzie.
Nagrywanie dźwięku
Gdy użytkownik przyzna uprawnienia do nagrywania, możesz nagrywać dźwięk i przetwarzać go w nagraniu.
Kotlin
val carAudioRecord = CarAudioRecord.create(carContext) carAudioRecord.startRecording() val data = ByteArray(CarAudioRecord.AUDIO_CONTENT_BUFFER_SIZE) while(carAudioRecord.read(data, 0, CarAudioRecord.AUDIO_CONTENT_BUFFER_SIZE) >= 0) { // Use data array // Potentially call carAudioRecord.stopRecording() if your processing finds end of speech } carAudioRecord.stopRecording()
Java
CarAudioRecord carAudioRecord = CarAudioRecord.create(getCarContext()); carAudioRecord.startRecording(); byte[] data = new byte[CarAudioRecord.AUDIO_CONTENT_BUFFER_SIZE]; while (carAudioRecord.read(data, 0, CarAudioRecord.AUDIO_CONTENT_BUFFER_SIZE) >= 0) { // Use data array // Potentially call carAudioRecord.stopRecording() if your processing finds end of speech } carAudioRecord.stopRecording();
Aktywność audio
W przypadku nagrywania z mikrofonu w samochodzie najpierw pobierz dźwięk zaznacz, aby i włącz wszystkie trwające multimedia. Jeśli utracisz aktywność audio, Zatrzymaj nagrywanie.
Oto przykład uzyskania aktywności audio:
Kotlin
val carAudioRecord = CarAudioRecord.create(carContext) // Take audio focus so that user's media is not recorded val audioAttributes = AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) // Use the most appropriate usage type for your use case .setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE) .build() val audioFocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) .setAudioAttributes(audioAttributes) .setOnAudioFocusChangeListener { state: Int -> if (state == AudioManager.AUDIOFOCUS_LOSS) { // Stop recording if audio focus is lost carAudioRecord.stopRecording() } } .build() if (carContext.getSystemService(AudioManager::class.java) .requestAudioFocus(audioFocusRequest) != AudioManager.AUDIOFOCUS_REQUEST_GRANTED ) { // Don't record if the focus isn't granted return } carAudioRecord.startRecording() // Process the audio and abandon the AudioFocusRequest when done
Java
CarAudioRecord carAudioRecord = CarAudioRecord.create(getCarContext()); // Take audio focus so that user's media is not recorded AudioAttributes audioAttributes = new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) // Use the most appropriate usage type for your use case .setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE) .build(); AudioFocusRequest audioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) .setAudioAttributes(audioAttributes) .setOnAudioFocusChangeListener(state -> { if (state == AudioManager.AUDIOFOCUS_LOSS) { // Stop recording if audio focus is lost carAudioRecord.stopRecording(); } }) .build(); if (getCarContext().getSystemService(AudioManager.class).requestAudioFocus(audioFocusRequest) != AUDIOFOCUS_REQUEST_GRANTED) { // Don't record if the focus isn't granted return; } carAudioRecord.startRecording(); // Process the audio and abandon the AudioFocusRequest when done
Biblioteka testów
Testowanie Androida do samochodu
Biblioteka – element pomocniczy
klas, za pomocą których możesz zweryfikować działanie aplikacji w środowisku testowym.
Na przykład parametr
SessionController
pozwala symulować połączenie z hostem i sprawdzić, czy
Screen
i
Utworzenie Template
i
.
Zapoznaj się z Sample .
Zgłaszanie problemu z biblioteką aplikacji Android do samochodu
Jeśli znajdziesz problem z biblioteką, zgłoś go za pomocą Google Issue Tracker. Pamiętaj, aby w szablonie problemu podać wszystkie wymagane informacje.
Zanim zgłosisz nowy numer, sprawdź, czy jest on uwzględniony w wersji biblioteki notatki lub raporty na liście problemów. Możesz zasubskrybować kanał i głosować na problemy przez kliknij gwiazdkę, aby zgłosić problem z trackerem. Więcej informacji: Subskrybowanie problemu.