Użyj interfejsu API zestawu wskaźników (interfejs API systemu Android), aby wyświetlać aplikacje nawigacyjne, w tym Mapy Google, na dodatkowym wyświetlaczu w samochodzie, na przykład za kierownicą na desce rozdzielczej. Na tej stronie opisano, jak utworzyć usługę sterującą tym dodatkowym wyświetlaczem, a następnie zintegrować tę usługę z
, aby aplikacje nawigacyjne mogły wyświetlać interfejs użytkownika.CarService
Terminologia
Na tej stronie używane są następujące terminy:
Termin | Opis |
---|---|
CarInstrumentClusterManager | Instancja CarManager , która umożliwia aplikacjom zewnętrznym uruchamianie działań w zestawie wskaźników i otrzymywanie wywołań zwrotnych, gdy zestaw wskaźników jest gotowy do wyświetlania działań. |
CarManager | Klasa podstawowa wszystkich menedżerów używanych przez aplikacje zewnętrzne do interakcji z usługami specyficznymi dla samochodu realizowanymi przez CarService . |
CarService | Usługa platformy Android zapewniająca komunikację między aplikacjami zewnętrznymi (w tym Mapami Google) i funkcjami specyficznymi dla samochodu, takimi jak dostęp do zestawu wskaźników. |
Miejsce docelowe | Ostateczny cel, do którego będzie nawigował pojazd. |
ETA | Szacowany czas dotarcia do celu. |
Jednostka główna (HU) | Podstawowa jednostka obliczeniowa wbudowana w samochód. HU obsługuje cały kod Androida i jest podłączony do centralnego wyświetlacza w samochodzie. |
Klaster instrumentów | Wyświetlacz dodatkowy umieszczony za kierownicą i pomiędzy przyrządami samochodowymi. Może to być niezależna jednostka obliczeniowa podłączona do HU poprzez sieć wewnętrzną samochodu (magistrala CAN) lub dodatkowy wyświetlacz podłączony do HU. |
InstrumentClusterRenderingService | Klasa bazowa usługi używanej do komunikacji z wyświetlaczem zestawu wskaźników. Producenci OEM muszą zapewnić rozszerzenie tej klasy, które współdziała ze sprzętem specyficznym dla OEM. |
Aplikacja KitchenSink | Aplikacja testowa dołączona do Android Automotive. |
Trasa | Określona trasa, po której porusza się pojazd, aby dotrzeć do celu. |
Usługa Singletona | Usługa systemu Android z atrybutem android:singleUser . W danym momencie maksymalnie jedna instancja usługi działa na systemie Android. |
Warunki wstępne
Aby rozwinąć integrację, pamiętaj o posiadaniu tych elementów:
- Środowisko programistyczne Androida. Aby skonfigurować środowisko programistyczne systemu Android, zobacz Wymagania dotyczące kompilacji .
- Pobierz kod źródłowy Androida. Pobierz najnowszą wersję kodu źródłowego Androida z gałęzi pi-car-release (lub nowszej) pod adresem https://android.googlesource.com .
- Jednostka główna (HU). Urządzenie z Androidem, na którym można uruchomić system Android 9 (lub nowszy). To urządzenie musi mieć własny wyświetlacz i mieć możliwość flashowania wyświetlacza w nowych wersjach Androida.
- Zestaw wskaźników to jeden z następujących elementów:
- Fizyczny wyświetlacz dodatkowy podłączony do HU. Jeśli sprzęt i jądro urządzenia obsługują zarządzanie wieloma wyświetlaczami.
- Niezależna jednostka. Dowolna jednostka obliczeniowa podłączona do HU za pośrednictwem połączenia sieciowego, zdolna do odbierania i wyświetlania strumienia wideo na własnym wyświetlaczu.
- Emulowany wyświetlacz. Podczas programowania możesz użyć jednego z następujących emulowanych środowisk:
- Symulowane wyświetlacze wtórne. Aby włączyć symulowany ekran dodatkowy w dowolnej dystrybucji AOSP Androida, przejdź do ustawień Opcji programisty w aplikacji systemowej Ustawienia, a następnie wybierz Symuluj wyświetlacze dodatkowe. Ta konfiguracja jest równoznaczna z podłączeniem fizycznego dodatkowego wyświetlacza, z tym ograniczeniem, że ten wyświetlacz jest nałożony na główny wyświetlacz.
- Emulowany zestaw wskaźników. Emulator Androida dołączony do Android Automotive umożliwia wyświetlanie zestawu wskaźników z usługą ClusterRenderingService podłączoną do dodatkowego wyświetlacza. emulator _qemu-pipes . Usługa ClusterRenderingService jest podłączona do dodatkowego wyświetlacza.
referencyjna implementacja zestawu wskaźników, aby połączyć się z tym emulowanym wyświetlaczem zewnętrznym.
Architektura integracji
Komponenty integracyjne
Każda integracja interfejsu API klastra instrumentów składa się z trzech komponentów:
-
CarService
- Aplikacje nawigacyjne
- Usługa klastra przyrządów OEM
Serwis samochodowy
CarService
pośredniczy między aplikacjami nawigacyjnymi a samochodem, zapewniając, że w danym momencie tylko jedna aplikacja nawigacyjna jest aktywna i tylko aplikacje z uprawnieniem android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL
mogą przesyłać dane do samochodu.
CarService
ładuje wszystkie usługi specyficzne dla samochodu i zapewnia dostęp do tych usług za pośrednictwem szeregu menedżerów. Aby móc wchodzić w interakcję z usługami, aplikacje działające w samochodzie mogą uzyskać dostęp do tych menedżerów.
Aby wdrożyć zestaw wskaźników, producenci OEM z branży motoryzacyjnej muszą utworzyć niestandardową implementację InstrumentClusterRendererService i zaktualizować usługę ClusterRenderingService podłączoną do dodatkowego wyświetlacza.
Podczas renderowania zestawu wskaźników podczas procesu uruchamiania CarService
odczytuje klucz InstrumentClusterRendererService
usługi ClusterRenderingService podłączonej do dodatkowego wyświetlacza. aby zlokalizować implementację InstrumentClusterService
. W AOSP ten wpis wskazuje na usługę renderowania przykładowej implementacji klastra interfejsu API nawigacji stanu:
<string name="instrumentClusterRendererService"> android.car.cluster/.ClusterRenderingService </string>
Usługa, o której mowa w tym wpisie, jest inicjowana i powiązana z CarService
. Gdy aplikacje nawigacyjne, takie jak Mapy Google, żądają CarInstrumentClusterManager
, CarService
udostępnia menedżera, który aktualizuje stan zestawu wskaźników z powiązanej InstrumentClusterRenderingService
. (W tym przypadku związany odnosi się do usług Androida .)
Usługa klastra instrumentów
Producenci OEM muszą utworzyć pakiet Android (APK) zawierający podklasę usługi ClusterRenderingService podłączonej do dodatkowego wyświetlacza. Usługa ClusterRenderingService jest podłączona do dodatkowego wyświetlacza. dla próbki.
Klasa ta służy dwóm celom:
- Udostępnia interfejs Androida i urządzenie renderujące klaster instrumentów (cel tej strony).
- Odbiera i wyświetla aktualizacje stanu nawigacji, takie jak szczegółowe wskazówki nawigacyjne.
W pierwszym celu implementacje OEM InstrumentClusterRendererService
muszą zainicjować dodatkowy wyświetlacz używany do renderowania informacji na ekranach w kabinie samochodu i przekazać te informacje do CarService
poprzez wywołanie metod InstrumentClusterRendererService.setClusterActivityOptions()
i InstrumentClusterRendererService.setClusterActivityState()
.
W przypadku drugiej funkcji usługa Instrument Cluster musi zapewniać implementację usługi ClusterRenderingService podłączonej do dodatkowego wyświetlacza. interfejs odbierający zdarzenia aktualizacji statusu nawigacji, które są zakodowane jako eventType
i dane zdarzenia zakodowane w pakiecie.
Sekwencja całkowania
Poniższy diagram ilustruje implementację stanu nawigacji, który renderuje aktualizacje:
Na tej ilustracji kolory oznaczają:
- Żółty.
CarService
iCarNavigationStatusManager
udostępniane na platformie Android. Aby dowiedzieć się więcej, zobacz Samochód i CAR_NAVIGATION_SERVICE . - Cyjan.
InstrumentClusterRendererService
wdrożony przez producenta OEM. - Fioletowy. Aplikacja nawigacyjna wdrożona przez Google i zewnętrznych programistów.
- Zielony.
CarAppFocusManager
. Aby dowiedzieć się więcej, zobacz Korzystanie z interfejsu API CarAppFocusManager poniżej i CarAppFocusManager .
Przepływ informacji o stanie nawigacji przebiega w następującej kolejności:
-
CarService
inicjuje usługęInstrumentClusterRenderingService
. - Podczas inicjalizacji
InstrumentClusterRenderingService
aktualizujeCarService
o:- Właściwości wyświetlania zestawu wskaźników, takie jak widoczne granice (więcej szczegółów na temat niewidocznych granic znajdziesz później).
- Opcje działań potrzebne do uruchomienia działań na wyświetlaczu zestawu wskaźników (więcej szczegółów znajdziesz w ActivityOptions .
- Aplikacja nawigacyjna (taka jak Google Maps dla Android Automotive lub dowolna aplikacja mapowa z wymaganymi uprawnieniami):
- Uzyskuje
CarAppFocusManager
przy użyciu klasy Car z car-lib. - Przed rozpoczęciem szczegółowych wskazówek wywoływana jest funkcja
CarAppFocusManager.requestFocus()
w celu przekazaniaCarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION
jako parametruappType
.
- Uzyskuje
-
CarAppFocusManager
przekazuje to żądanie doCarService
. Jeśli zostanie przyznana,CarService
sprawdza pakiet aplikacji nawigacyjnej i lokalizuje aktywność oznaczoną kategoriąandroid.car.cluster.NAVIGATION
. - Jeśli zostanie znaleziona, aplikacja nawigacyjna korzysta z
ActivityOptions
zgłoszonych przezInstrumentClusterRenderingService
w celu uruchomienia działania i uwzględnia właściwości wyświetlania zestawu wskaźników jako dodatki w zamierzeniu.
Zintegruj interfejs API
Implementacja InstrumentClusterRenderingService
musi:
- Zostań wyznaczony jako usługa pojedyncza, dodając następującą wartość do pliku AndroidManifest.xml. Jest to konieczne, aby zapewnić działanie pojedynczej kopii usługi klastra przyrządów, nawet podczas inicjalizacji i przełączania użytkowników:
android:singleUser="true"
- Przytrzymaj uprawnienia systemowe
BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE
. Gwarantuje to, że tylko usługa renderowania zestawu wskaźników zawarta w obrazie systemu Android będzie zawsze powiązana zCarService
:<uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
Zaimplementuj usługę InstrumentClusterRenderingService
Aby zbudować usługę:
- Napisz klasę, która rozszerza usługę ClusterRenderingService podłączoną do dodatkowego wyświetlacza. a następnie dodaj odpowiedni wpis do pliku
- Podczas
onCreate()
użyj tej usługi, aby zainicjować komunikację ze sprzętem renderującym. Opcje obejmują:- Określ drugi wyświetlacz, który ma być używany w zestawie wskaźników.
- Utwórz wirtualny wyświetlacz, aby aplikacja Instrument Cluster renderowała i przesyłała wyrenderowany obraz do jednostki zewnętrznej (przy użyciu formatu strumieniowego przesyłania wideo, takiego jak H.264).
- Gdy wyświetlacz wskazany powyżej będzie gotowy, usługa ta musi wywołać
InstrumentClusterRenderingService#setClusterActivityLaunchOptions()
, aby zdefiniować dokładneActivityOptions
, które muszą zostać użyte do wyświetlenia działania w zestawie wskaźników. Użyj tych parametrów:- Kategoria. Usługa ClusterRenderingService jest podłączona do dodatkowego wyświetlacza.
-
ActivityOptions.
InstancjaActivityOptions
, której można użyć do uruchomienia działania w zestawie wskaźników. Na przykład z przykładowej implementacji klastra instrumentów w AOSP:getService().setClusterActivityLaunchOptions( CATEGORY_NAVIGATION, ActivityOptions.makeBasic() .setLaunchDisplayId(displayId));
- Gdy klaster instrumentów jest gotowy do wyświetlania działań, ta usługa musi wywołać
InstrumentClusterRenderingService#setClusterActivityState()
. Użyj tych parametrów:-
category
Usługa ClusterRenderingService jest podłączona do dodatkowego wyświetlacza. - pakiet
state
wygenerowany za pomocą usługi ClusterRenderingService jest podłączony do dodatkowego wyświetlacza. Pamiętaj o podaniu następujących danych: -
visible
Określa zestaw wskaźników jako widoczny i gotowy do wyświetlania treści. -
unobscuredBounds
Prostokąt określający obszar na wyświetlaczu zestawu wskaźników, w którym można bezpiecznie wyświetlać treść. Na przykład obszary objęte tarczami i wskaźnikami.
-
- Zastąp metodę
Service#dump()
i zgłoś informacje o stanie przydatne do debugowania (więcej informacji można znaleźć w dumpsys ).
AndroidManifest.xml
. Ta klasa steruje wyświetlaniem zestawu wskaźników i może ( opcjonalnie ) renderować dane API stanu nawigacji.Przykładowa implementacja InstrumentClusterRenderingService
Poniższy przykład przedstawia implementację InstrumentClusterRenderingService
, która tworzy VirtualDisplay
w celu prezentacji zawartości klastra instrumentów na zdalnym fizycznym wyświetlaczu.
Alternatywnie, kod ten może przekazać displayId
dodatkowego fizycznego wyświetlacza podłączonego do HU, jeśli wiadomo, że taki jest dostępny.
/** * Sample {@link InstrumentClusterRenderingService} implementation */ public class SampleClusterServiceImpl extends InstrumentClusterRenderingService { // Used to retrieve or create displays private final DisplayManager mDisplayManager; // Unique identifier for the display to be used for instrument // cluster private final String mUniqueId = UUID.randomUUID().toString(); // Format of the instrument cluster display private static final int DISPLAY_WIDTH = 1280; private static final int DISPLAY_HEIGHT = 720; private static final int DISPLAY_DPI = 320; // Area not covered by instruments private static final int DISPLAY_UNOBSCURED_LEFT = 40; private static final int DISPLAY_UNOBSCURED_TOP = 0; private static final int DISPLAY_UNOBSCURED_RIGHT = 1200; private static final int DISPLAY_UNOBSCURED_BOTTOM = 680; @Override public void onCreate() { super.onCreate(); // Create a virtual display to render instrument cluster activities on mDisplayManager = getSystemService(DisplayManager.class); VirtualDisplay display = mDisplayManager.createVirtualDisplay( mUniqueId, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_DPI, null, 0 /* flags */, null, null); // Do any additional initialization (e.g.: start a video stream // based on this virtual display to present activities on a remote // display). onDisplayReady(display.getDisplay()); } private void onDisplayReady(Display display) { // Report activity options that should be used to launch activities on // the instrument cluster. String category = CarInstrumentClusterManager.CATEGORY_NAVIGATION; ActionOptions options = ActivityOptions.makeBasic() .setLaunchDisplayId(display.getDisplayId()); setClusterActivityOptions(category, options); // Report instrument cluster state. Rect unobscuredBounds = new Rect(DISPLAY_UNOBSCURED_LEFT, DISPLAY_UNOBSCURED_TOP, DISPLAY_UNOBSCURED_RIGHT, DISPLAY_UNOBSCURED_BOTTOM); boolean visible = true; ClusterActivityState state = ClusterActivityState.create(visible, unobscuredBounds); setClusterActivityState(category, options); } }
Użyj interfejsu API CarAppFocusManager
Interfejs API CarAppFocusManager udostępnia metodę o nazwie getAppTypeOwner()
, która pozwala usłudze klastrowania napisanej przez producentów OEM dowiedzieć się, która aplikacja nawigacyjna jest w danym momencie aktywna. Producenci OEM mogą użyć istniejącej metody CarAppFocusManager#addFocusListener()
, a następnie użyć getAppTypeOwner()
, aby dowiedzieć się, która aplikacja jest aktywna. Dzięki tym informacjom producenci OEM mogą:
- Przełącz aktywność pokazaną w klastrze na aktywność klastra zapewnioną przez aplikację nawigacyjną, która jest aktywna.
- Potrafi wykryć, czy skupiona aplikacja nawigacyjna ma aktywność klastra, czy nie. Jeśli skupiona aplikacja nawigacyjna nie ma aktywności klastra (lub jeśli taka aktywność jest wyłączona), producenci OEM mogą wysłać ten sygnał do samochodowego DIM, aby całkowicie pominąć aspekt nawigacji klastra.
Użyj CarAppFocusManager
aby ustawić i nasłuchiwać bieżącego fokusu aplikacji, takiego jak aktywna nawigacja lub polecenie głosowe. Zwykle w systemie aktywnie działa (lub jest skupiona) tylko jedna instancja takiej aplikacji.
Użyj metody CarAppFocusManager#addFocusListener(..)
, aby nasłuchiwać zmian fokusu aplikacji:
import android.car.CarAppFocusManager; ... Car car = Car.createCar(this); mAppFocusManager = (CarAppFocusManager)car.getCarManager(Car.APP_FOCUS_SERVICE); mAppFocusManager.addFocusListener(this, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION); ... public void onAppFocusChanged(int appType, boolean active) { // Use the CarAppFocusManager#getAppTypeOwner(appType) method call // to retrieve a list of active package names }
Użyj metody CarAppFocusManager#getAppTypeOwner(..)
, aby pobrać nazwy pakietów bieżącego właściciela danego typu aplikacji, na którym się skupia. Ta metoda może zwrócić więcej niż jedną nazwę pakietu, jeśli bieżący właściciel korzysta z funkcji android:sharedUserId
.
import android.car.CarAppFocusManager; ... Car car = Car.createCar(this); mAppFocusManager = (CarAppFocusManager)car.getCarManager(Car.APP_FOCUS_SERVICE); List<String> focusOwnerPackageNames = mAppFocusManager.getAppTypeOwner( CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION); if (focusOwnerPackageNames == null || focusOwnerPackageNames.isEmpty()) { // No Navigation app has focus // OEM may choose to show their default cluster view } else { // focusOwnerPackageNames // Use the PackageManager to retrieve the cluster activity for the package(s) // returned in focusOwnerPackageNames } ...
Dodatek: Skorzystaj z przykładowej aplikacji
AOSP udostępnia przykładową aplikację, która implementuje interfejs API stanu nawigacji.
Aby uruchomić tę przykładową aplikację:
- Kompiluj i flashuj Android Auto na obsługiwanym HU. Skorzystaj z instrukcji tworzenia i flashowania systemu Android specyficznych dla Twojego urządzenia. Aby uzyskać instrukcje, zobacz temat Korzystanie z tablic referencyjnych .
- Podłącz fizyczny dodatkowy wyświetlacz do HU (jeśli jest obsługiwany) lub włącz wirtualny dodatkowy wyświetlacz HU:
- Wybierz Tryb programisty w aplikacji Ustawienia.
- Wybierz Ustawienia > System > Zaawansowane > Opcje programistyczne > Symuluj dodatkowe wyświetlacze .
- Uruchom ponownie HU. Usługa ClusterRenderingService jest podłączona do dodatkowego wyświetlacza.
- Aby uruchomić aplikację KitchenSink:
- Otwórz szufladę.
- Przejdź do Inst. Klaster .
- Kliknij ROZPOCZNIJ METADANE .
KitchenSink żąda fokusu NAVIGATION, który instruuje usługę DirectRenderingCluster
, aby wyświetliła fałszywy interfejs użytkownika w zestawie wskaźników.