Android Auto i Android Automotive OS pomagają przenieść treści z aplikacji do multimediów użytkowników w samochodach. Aplikacja do multimediów dla samochodów musi udostępniać usługę przeglądarki multimediów do systemu Android Auto i Androida Automotive lub do innej aplikacji z multimediami przeglądarka może wykryć i wyświetlić Twoje treści.
W tym przewodniku przyjęto założenie, że masz już aplikację do multimediów, która odtwarza dźwięk na i czy jest ona zgodna z aplikacją do multimediów Androida .
W tym przewodniku opisano wymagane komponenty MediaBrowserService
i
MediaSession
, których potrzebuje Twoja aplikacja, aby działać na Androidzie Auto lub Androidzie
Automotive OS. Po ukończeniu podstawowej infrastruktury medialnej możesz
obsługę Androida Auto i wsparcie dotyczące:
system operacyjny Android Automotive do multimediów
.
Zanim zaczniesz
- Zapoznaj się z dokumentacją interfejsu Android Media API.
- Przeczytaj artykuł Tworzenie aplikacji do multimediów. .
- Przeczytaj najważniejsze terminy i koncepcje wymienione w tej sekcji.
Najważniejsze terminy i koncepcje
- Usługa przeglądarki multimediów
- Usługa na Androida zaimplementowana przez aplikację do multimediów zgodną z
MediaBrowserServiceCompat
. API. Aplikacja używa tej usługi do udostępniania swoich treści. - Przeglądarka multimediów
- Interfejs API używany przez aplikacje do multimediów do wykrywania i wyświetlania usług przeglądarki multimediów swoje treści. Android Auto i system operacyjny Android Automotive używają przeglądarki multimediów do znajdź usługę przeglądarki multimediów w aplikacji.
- Element multimedialny
Przeglądarka multimediów porządkuje zawartość w drzewie
MediaItem
obiektów. Element multimedialny może mieć jeden z tych flag albo oba:FLAG_PLAYABLE
: wskazuje, że element to liść na drzewie treści. Element reprezentuje pojedynczy strumień dźwięku, np. utwór z albumu, rozdział w audiobooku lub odcinek podcastu.FLAG_BROWSABLE
: wskazuje, że element jest węzłem w drzewie treści i że ma dzieci. Na przykład element reprezentuje album, a jego elementy podrzędne są utworów z albumu.
Element multimedialny, który można przeglądać i odtwarzać, działa jak playlista. Dostępne opcje i wybierz ten element, aby bawić się wszystkimi jego dziećmi, lub przejrzyj jego zawartość dzieci.
- Zoptymalizowane pod kątem pojazdów
Działanie dla aplikacji na system operacyjny Android Automotive zgodnej z Wytyczne projektowe dotyczące systemu operacyjnego Android Automotive Interfejs tych aktywności nie jest rysowany przez system operacyjny Android Automotive, dlatego musi być zgodna z wytycznymi dotyczącymi projektowania. Zwykle zawiera większe docelowe elementy dotykowe i rozmiary czcionek, obsługuje tryb dzienny i nocny. i zwiększyć kontrast.
Interfejsy zoptymalizowane pod kątem pojazdów można wyświetlać tylko wtedy, gdy Ograniczenia dotyczące wygody użytkowników nie obowiązują, ponieważ może wymagać szerszej uwagi lub interakcji ze strony użytkownika. CUXR nie działają, gdy samochód jest zatrzymywany lub zaparkowany, ale zawsze jest aktywny; gdy samochód jest w ruchu.
Nie musisz projektować działań dla Androida Auto, własny interfejs zoptymalizowany pod kątem pojazdu wykorzystuje informacje w usłudze przeglądarki multimediów.
Skonfiguruj pliki manifestu aplikacji
Zanim utworzysz usługę przeglądarki multimediów, musisz skonfigurować pliki manifestu aplikacji.
Zadeklarowanie usługi przeglądarki multimediów
Zarówno Android Auto, jak i system operacyjny Android Automotive łączą się z Twoją aplikacją przez w usłudze przeglądarki multimediów do przeglądania elementów multimedialnych. Deklarowanie multimediów usługa przeglądarki w pliku manifestu, aby umożliwić systemom operacyjnym Android Auto i Android Automotive znaleźć usługę i połączyć się z aplikacją.
Fragment kodu poniżej pokazuje, jak zadeklarować usługę przeglądarki multimediów pliku manifestu. Umieść ten kod w pliku manifestu swojej Moduł systemu operacyjnego Android Automotive oraz w pliku manifestu aplikacji na telefon.
<application>
...
<service android:name=".MyMediaBrowserService"
android:exported="true">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
...
</application>
Określ ikony aplikacji
Musisz określić ikony aplikacji, które mogą być dostępne na Androidzie Auto i Androidzie Automotive będzie reprezentować aplikację w interfejsie systemu. Wymagane są 2 rodzaje ikon:
- Ikona programu uruchamiającego
- Ikona informacji
Ikona programu uruchamiającego
Ikona Menu z aplikacjami reprezentuje Twoją aplikację w interfejsie systemowym, np. w Menu z aplikacjami i w panelu z ikonami. Możesz określić, czy ikona z Twoja aplikacja mobilna do reprezentowania aplikacji multimedialnej w samochodzie przy użyciu tego pliku manifestu deklaracja:
<application
...
android:icon="@mipmap/ic_launcher"
...
/>
Aby użyć innej ikony niż w aplikacji mobilnej, ustaw właściwość android:icon
w elemencie <service>
usługi przeglądarki multimediów w pliku manifestu:
<application>
...
<service
...
android:icon="@mipmap/auto_launcher"
...
/>
</application>
Ikona informacji
Ikona atrybucji jest używana w miejscach, gdzie pierwszeństwo mają treści multimedialne, np. na kartach multimedialnych. Rozważ ponowne wykorzystanie małej ikony używanej w powiadomieniach. Ta ikona musi być monochromatyczna. Możesz wybrać ikonę, która będzie reprezentować aplikację, korzystając z tej deklaracji w pliku manifestu:
<application>
...
<meta-data
android:name="androidx.car.app.TintableAttributionIcon"
android:resource="@drawable/ic_status_icon" />
...
</application>
Tworzenie usługi przeglądarki multimediów
Usługę przeglądarki multimediów można utworzyć przez rozszerzenie MediaBrowserServiceCompat
zajęcia. Zarówno Android Auto, jak i system operacyjny Android Automotive będą mogły korzystać z Twojej usługi
wykonaj następujące czynności:
- Przejrzyj hierarchię treści aplikacji, aby wyświetlić menu użytkownikowi.
- Uzyskiwanie tokena
MediaSessionCompat
aplikacji do sterowania odtwarzaniem dźwięku.
Możesz też użyć usługi przeglądarki multimediów, aby umożliwić innym klientom dostęp do treści multimedialnych z aplikacji Te klienty multimediów mogą być innymi aplikacjami przez telefon użytkownika lub mogą być innymi klientami zdalnymi.
Przepływ pracy w usłudze przeglądarki multimediów
Z tej sekcji dowiesz się, jak systemy operacyjne Android Automotive i Android Automotive Korzystaj z usługi przeglądarki multimediów automatycznie w trakcie typowego przepływu pracy użytkownika.
- Użytkownik uruchamia Twoją aplikację na Androidzie Automotive lub na Androidzie Auto.
- System operacyjny Android Automotive lub Android Auto kontaktuje się z przeglądarką multimediów w Twojej aplikacji
usługi za pomocą
onCreate()
. W Twojej implementacji usługionCreate()
musisz utworzyć i zarejestrowaćMediaSessionCompat
i jego obiekt wywołania zwrotnego. - System operacyjny Android Automotive lub Android Auto wywołuje numer
onGetRoot()
Twojej usługi. aby uzyskać główny element multimedialny w hierarchii treści. Główny element multimedialny nie jest wyświetlana. jest używany do pobierania dodatkowych treści z aplikacji. - System operacyjny Android Automotive lub Android Auto wywołuje numer Twojej usługi
onLoadChildren()
metody pobierania elementów podrzędnych głównego elementu multimedialnego. system operacyjny Android Automotive Android Auto wyświetla te elementy multimedialne jako elementy treści najwyższego poziomu. Zobacz Aby uzyskać więcej informacji, utwórz strukturę menu głównego na tej stronie z informacjami o oczekiwaniach systemu na tym poziomie. - Jeśli użytkownik wybierze element multimedialny, który można przeglądać,
onLoadChildren()
jest wywoływana ponownie, by pobrać elementy podrzędne wybranego elementu menu. - Jeśli użytkownik wybierze element multimedialny z możliwością odtwarzania, system operacyjny Android Automotive lub Android Automatycznie wywołuje odpowiednią metodę wywołania zwrotnego sesji multimediów, aby wykonać to działanie.
- Jeśli aplikacja obsługuje tę funkcję, użytkownik może też wyszukiwać Twoje treści. W tym
etui na system operacyjny Android Automotive lub Android Auto
onSearch()
.
Tworzenie hierarchii treści
Android Auto i Android Automotive OS nawiązują połączenie z usługą przeglądarki multimediów w Twojej aplikacji, aby
aby dowiedzieć się, jakie treści są dostępne. Musisz wdrożyć 2 metody w ramach
usługa przeglądarki multimediów, która obsługuje tę funkcję: onGetRoot()
oraz
onLoadChildren()
Wdróż onGetRoot
onGetRoot()
Twojej usługi
zwraca informacje o węźle głównym hierarchii treści.
Android Auto i Android Automotive OS używają tego węzła głównego, aby zażądać pozostałej części
za pomocą
onLoadChildren()
.
Ten fragment kodu pokazuje prostą implementację
Metoda onGetRoot()
:
Kotlin
override fun onGetRoot( clientPackageName: String, clientUid: Int, rootHints: Bundle? ): BrowserRoot? = // Verify that the specified package is allowed to access your // content. You'll need to write your own logic to do this. if (!isValid(clientPackageName, clientUid)) { // If the request comes from an untrusted package, return null. // No further calls will be made to other media browsing methods. null } else MediaBrowserServiceCompat.BrowserRoot(MY_MEDIA_ROOT_ID, null)
Java
@Override public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) { // Verify that the specified package is allowed to access your // content. You'll need to write your own logic to do this. if (!isValid(clientPackageName, clientUid)) { // If the request comes from an untrusted package, return null. // No further calls will be made to other media browsing methods. return null; } return new MediaBrowserServiceCompat.BrowserRoot(MY_MEDIA_ROOT_ID, null); }
Bardziej szczegółowy przykład tej metody znajdziesz tutaj: onGetRoot()
w przykładowej aplikacji Universal Android Music Player na GitHubie.
Dodaj weryfikację pakietu dla onGetRoot()
Po nawiązaniu połączenia z numerem onGetRoot()
usługi
pakiet wywołujący przekazuje do Twojej usługi informacje identyfikacyjne. Twoje
na podstawie tych informacji decyduje, czy pakiet ma dostęp do
treści. Możesz np. ograniczyć dostęp do treści aplikacji do listy
zatwierdzonych pakietów, porównując clientPackageName
z listą dozwolonych i
weryfikację certyfikatu użytego do podpisania pliku APK pakietu. Jeśli pakiet nie może
zostaną zweryfikowane, wróć do null
, by odmówić dostępu do treści.
Aby udostępnić aplikacje systemowe, takie jak Android Auto czy system operacyjny Android Automotive,
z dostępem do Twoich treści, usługa musi zawsze zwracać wartość inną niż zero
BrowserRoot
, gdy te aplikacje systemowe wywołują onGetRoot()
. Podpis aplikacji systemu operacyjnego Android Automotive może się różnić w zależności od
marki i modelu samochodu, musisz więc zezwalać na połączenia
do sprawnej obsługi systemu operacyjnego Android Automotive.
Fragment kodu poniżej pokazuje, jak za pomocą usługi możesz sprawdzić, czy Pakiet do wykonywania połączeń to aplikacja systemowa:
fun isKnownCaller(
callingPackage: String,
callingUid: Int
): Boolean {
...
val isCallerKnown = when {
// If the system is making the call, allow it.
callingUid == Process.SYSTEM_UID -> true
// If the app was signed by the same certificate as the platform
// itself, also allow it.
callerSignature == platformSignature -> true
// ... more cases
}
return isCallerKnown
}
Ten fragment kodu jest cytatem z PackageValidator
w przykładowej aplikacji Universal Android Music Player na GitHubie. Wyświetl te zajęcia
.
onGetRoot()
.
Oprócz zezwalania na aplikacje systemowe musisz też zezwolić Asystentowi Google
połączyć się z urządzeniem MediaBrowserService
. Pamiętaj, że Asystent Google ma
osobne nazwy pakietów
na telefon (w tym Androida Auto) i system operacyjny Android Automotive.
Wdróż onLoadChildren()
Po otrzymaniu obiektu węzła głównego, Androida Auto i systemu operacyjnego Android Automotive
i utwórz menu najwyższego poziomu, dzwoniąc pod numer onLoadChildren()
na obiekcie węzła głównego, aby pobrać jego elementy podrzędne. Aplikacje klienckie tworzą podmenu według
tę samą metodę przy użyciu obiektów węzłów podrzędnych.
Każdy węzeł w hierarchii treści jest reprezentowany przez MediaBrowserCompat.MediaItem
obiektu. Każdy z tych elementów multimedialnych jest identyfikowany za pomocą unikalnego ciągu identyfikatora. Klient
aplikacje traktują te ciągi identyfikatorów jako nieprzezroczyste tokeny. Gdy aplikacja kliencka chce przeglądać internet
do menu podrzędnego lub odtwarzania elementu multimedialnego, przekazuje token. To Twoja aplikacja jest odpowiedzialna
Powiązanie tokena z odpowiednim elementem multimedialnym.
Ten fragment kodu pokazuje prostą implementację atrybutu onLoadChildren()
:
Kotlin
override fun onLoadChildren( parentMediaId: String, result: Result<List<MediaBrowserCompat.MediaItem>> ) { // Assume for example that the music catalog is already loaded/cached. val mediaItems: MutableList<MediaBrowserCompat.MediaItem> = mutableListOf() // Check whether this is the root menu: if (MY_MEDIA_ROOT_ID == parentMediaId) { // Build the MediaItem objects for the top level // and put them in the mediaItems list. } else { // Examine the passed parentMediaId to see which submenu we're at // and put the children of that menu in the mediaItems list. } result.sendResult(mediaItems) }
Java
@Override public void onLoadChildren(final String parentMediaId, final Result<List<MediaBrowserCompat.MediaItem>> result) { // Assume for example that the music catalog is already loaded/cached. List<MediaBrowserCompat.MediaItem> mediaItems = new ArrayList<>(); // Check whether this is the root menu: if (MY_MEDIA_ROOT_ID.equals(parentMediaId)) { // Build the MediaItem objects for the top level // and put them in the mediaItems list. } else { // Examine the passed parentMediaId to see which submenu we're at // and put the children of that menu in the mediaItems list. } result.sendResult(mediaItems); }
Pełny przykład tej metody znajdziesz w
onLoadChildren()
w przykładowej aplikacji Universal Android Music Player na GitHubie.
Uporządkuj menu główne
Android Auto i Android Automotive OS mają określone ograniczenia dotyczące
do struktury menu głównego. Są one przekazywane do MediaBrowserService
za pomocą wskazówek pierwiastkowych, które można odczytać za pomocą argumentu Bundle
przekazywanego do
onGetRoot()
.
Stosując się do tych wskazówek, system optymalnie wyświetla zawartość główną
jako kart nawigacyjnych. Jeśli nie zastosujesz się do tych wskazówek, niektóre treści główne mogą
zostaną usunięte lub staną się mniej widoczne dla systemu. Wysyłane są 2 podpowiedzi:
- Limit liczby elementów podrzędnych: w większości przypadków powinien to być 4. Oznacza to, że Nie można wyświetlić więcej niż 4 kart.
- Obsługiwane flagi elementów głównych podrzędnych:
możesz spodziewać się
MediaItem#FLAG_BROWSABLE
. Oznacza to, że jako karty mogą być wyświetlane tylko elementy, które można przeglądać, a nie elementy, których można odtworzyć.
Użyj tego kodu, aby odczytać odpowiednie wskazówki dotyczące poziomu głównego:
Kotlin
import androidx.media.utils.MediaConstants // Later, in your MediaBrowserServiceCompat. override fun onGetRoot( clientPackageName: String, clientUid: Int, rootHints: Bundle ): BrowserRoot { val maximumRootChildLimit = rootHints.getInt( MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_LIMIT, /* defaultValue= */ 4) val supportedRootChildFlags = rootHints.getInt( MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_SUPPORTED_FLAGS, /* defaultValue= */ MediaItem.FLAG_BROWSABLE) // Rest of method... }
Java
import androidx.media.utils.MediaConstants; // Later, in your MediaBrowserServiceCompat. @Override public BrowserRoot onGetRoot( String clientPackageName, int clientUid, Bundle rootHints) { int maximumRootChildLimit = rootHints.getInt( MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_LIMIT, /* defaultValue= */ 4); int supportedRootChildFlags = rootHints.getInt( MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_SUPPORTED_FLAGS, /* defaultValue= */ MediaItem.FLAG_BROWSABLE); // Rest of method... }
Możesz zastosować rozgałęzienie logiki w strukturze hierarchii treści
opartych na wartościach tych wskazówek, zwłaszcza jeśli Twoja hierarchia różni się
Integracje z MediaBrowser
poza systemem operacyjnym Android Auto i Androidem Automotive.
Jeśli na przykład zwykle wyświetlasz główny element gry, możesz go zagnieździć.
ze względu na wartość obsługiwanych flag
wskazówkę.
Oprócz podstawowych wskazówek warto stosować się do kilku dodatkowych wskazówek aby zapewnić optymalne renderowanie kart:
- Dla każdego elementu karty dodaj monochromatyczne, najlepiej białe ikony.
- Każdy element na karcie powinien mieć krótkie, ale przydatne etykiety. Krótkie etykiety zmniejsza ryzyko obcięcia ciągu.
Wyświetl grafikę multimedialną
Grafika elementów multimedialnych musi być przekazywana jako lokalny identyfikator URI za pomocą jednej z tych metod
ContentResolver.SCHEME_CONTENT
lub ContentResolver.SCHEME_ANDROID_RESOURCE
.
Ten lokalny identyfikator URI musi wskazywać format bitmapy lub wektorowy obiekt rysowalny w
i zasobach aplikacji. Dla obiektów MediaDescriptionCompat
reprezentujących elementy w
w hierarchii treści, przekaż identyfikator URI za pomocą setIconUri()
.
W przypadku obiektów MediaMetadataCompat
reprezentujących aktualnie odtwarzany element, przekaż parametr
Identyfikator URI do putString()
,
przy użyciu dowolnego z tych kluczy:
MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI
MediaMetadataCompat.METADATA_KEY_ART_URI
MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI
Poniższe kroki opisują, jak pobrać grafikę z internetowego identyfikatora URI i udostępnić
za pomocą lokalnego identyfikatora URI. Aby uzyskać pełniejszy przykład, zobacz
implementacja
openFile()
oraz metody otoczenia w Universal Android Music
Przykładowa aplikacja odtwarzacza.
Utwórz identyfikator URI
content://
odpowiadający identyfikatorowi URI sieci. Przeglądarka multimediów i sesji multimediów, które przekazują ten identyfikator URI treści do Androida Auto, system operacyjny Android Automotive.Kotlin
fun Uri.asAlbumArtContentURI(): Uri { return Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) .authority(CONTENT_PROVIDER_AUTHORITY) .appendPath(this.getPath()) // Make sure you trust the URI .build() }
Java
public static Uri asAlbumArtContentURI(Uri webUri) { return new Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) .authority(CONTENT_PROVIDER_AUTHORITY) .appendPath(webUri.getPath()) // Make sure you trust the URI! .build(); }
W implementacji
ContentProvider.openFile()
sprawdź, czy plik dla odpowiedniego identyfikatora URI. Jeśli nie, pobierz plik obrazu i zapisz go w pamięci podręcznej. ten fragment kodu używa Glide.Kotlin
override fun openFile(uri: Uri, mode: String): ParcelFileDescriptor? { val context = this.context ?: return null val file = File(context.cacheDir, uri.path) if (!file.exists()) { val remoteUri = Uri.Builder() .scheme("https") .authority("my-image-site") .appendPath(uri.path) .build() val cacheFile = Glide.with(context) .asFile() .load(remoteUri) .submit() .get(DOWNLOAD_TIMEOUT_SECONDS, TimeUnit.SECONDS) cacheFile.renameTo(file) file = cacheFile } return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY) }
Java
@Nullable @Override public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) throws FileNotFoundException { Context context = this.getContext(); File file = new File(context.getCacheDir(), uri.getPath()); if (!file.exists()) { Uri remoteUri = new Uri.Builder() .scheme("https") .authority("my-image-site") .appendPath(uri.getPath()) .build(); File cacheFile = Glide.with(context) .asFile() .load(remoteUri) .submit() .get(DOWNLOAD_TIMEOUT_SECONDS, TimeUnit.SECONDS); cacheFile.renameTo(file); file = cacheFile; } return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); }
Szczegółowe informacje o dostawcach treści znajdziesz w sekcji Tworzenie treści Google Cloud Platform.
Zastosuj style treści
Po zbudowaniu hierarchii treści za pomocą elementów, które można przeglądać lub grać, mogą stosować style treści, które określają sposób wyświetlania tych elementów w samochodzie.
Możesz używać tych stylów treści:
- Pozycje na liście
-
Ten styl treści traktuje priorytetowo tytuły i metadane niż obrazy.
- Elementy siatki
-
Ten styl treści traktuje obrazy priorytetowo, a nie tytuły i metadane.
Ustaw domyślne style treści
Możesz ustawić globalne domyślne ustawienia wyświetlania elementów multimedialnych, dodając
określone stałe w pakiecie dodatków BrowserRoot
Twojej usługi
onGetRoot()
.
. Android Auto i system operacyjny Android Automotive odczytują ten pakiet i szukają
aby określić właściwy styl.
W pakiecie jako klucze można użyć tych elementów:
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE
: wskazuje wskazówkę do prezentacji dotyczącą wszystkich elementów w drzewie przeglądania, które można przeglądać.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE
: wskazuje wskazówkę do prezentacji dotyczącą wszystkich elementów możliwych do odtworzenia w drzewie przeglądania.
Klucze mogą być mapowane na następujące stałe wartości całkowite, aby wpływać na prezentację tych elementów:
DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM
: odpowiednie elementy są wyświetlane jako elementy listy.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM
: odpowiednie elementy są wyświetlane jako elementy siatki.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM
: odpowiednie produkty są wyświetlane jako „kategoria” elementów listy. Są to takie same jak zwykłe elementy listy, ale marginesy są nakładane tych elementów bo małe ikony wyglądają lepiej. Ikony muszą być obiektami rysowalnymi wektorowo z możliwością zabarwienia. Ta wskazówka powinna być dostarczana tylko dla elementów, które można przeglądać.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_GRID_ITEM
: odpowiednie produkty są wyświetlane jako „kategoria” elementów siatki. Są to takie same jak w zwykłych elementach siatki, z tym że marginesy są nakładane tych elementów bo małe ikony wyglądają lepiej. Ikony muszą być obiektami rysowalnymi wektorowo z możliwością zabarwienia. Ta wskazówka powinna być dostarczana tylko dla elementów, które można przeglądać.
Poniższy fragment kodu pokazuje, jak ustawić domyślny styl treści dla elementów, które można przeglądać, do siatek lub elementów gier, aby utworzyć listy:
Kotlin
import androidx.media.utils.MediaConstants @Nullable override fun onGetRoot( @NonNull clientPackageName: String, clientUid: Int, @Nullable rootHints: Bundle ): BrowserRoot { val extras = Bundle() extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM) extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM) return BrowserRoot(ROOT_ID, extras) }
Java
import androidx.media.utils.MediaConstants; @Nullable @Override public BrowserRoot onGetRoot( @NonNull String clientPackageName, int clientUid, @Nullable Bundle rootHints) { Bundle extras = new Bundle(); extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM); extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM); return new BrowserRoot(ROOT_ID, extras); }
Ustawianie stylów treści dla poszczególnych elementów
Interfejs Content Style API umożliwia zastąpienie domyślnego stylu treści elementów multimedialnych możliwych do przeglądania, a także samego elementu multimedialnego.
Aby zastąpić domyślne ustawienia w przypadku elementów podrzędnych elementu multimedialnego, które można przeglądać, utwórz
pakietu dodatków w MediaDescription
elementu multimedialnego, a następnie dodać tę samą wartość
wspomnianych wcześniej wskazówek. DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE
dotyczy gier potomnych danego elementu, a
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE
ma zastosowanie do:
które dzieci mogą
oglądać.
Aby zastąpić ustawienia domyślne samego konkretnego elementu multimedialnego, nie jego
dzieci, utwórz pakiet dodatków w elemencie MediaDescription
elementu multimedialnego
i dodaj wskazówkę z kluczem
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM
Aby określić sposób prezentacji elementu, użyj tych samych wartości co w poprzednim kroku.
Ten fragment kodu pokazuje, jak utworzyć możliwy do przeglądania element MediaItem
, który
zastępuje domyślny styl treści zarówno sobie, jak i jego elementów podrzędnych. Styl
jako element listy kategorii, jego elementy podrzędne, które można przeglądać, a elementy listy,
gry dziecięce jako elementy siatki:
Kotlin
import androidx.media.utils.MediaConstants private fun createBrowsableMediaItem( mediaId: String, folderName: String, iconUri: Uri ): MediaBrowser.MediaItem { val mediaDescriptionBuilder = MediaDescription.Builder() mediaDescriptionBuilder.setMediaId(mediaId) mediaDescriptionBuilder.setTitle(folderName) mediaDescriptionBuilder.setIconUri(iconUri) val extras = Bundle() extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM) extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM) extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM) mediaDescriptionBuilder.setExtras(extras) return MediaBrowser.MediaItem( mediaDescriptionBuilder.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE) }
Java
import androidx.media.utils.MediaConstants; private MediaBrowser.MediaItem createBrowsableMediaItem( String mediaId, String folderName, Uri iconUri) { MediaDescription.Builder mediaDescriptionBuilder = new MediaDescription.Builder(); mediaDescriptionBuilder.setMediaId(mediaId); mediaDescriptionBuilder.setTitle(folderName); mediaDescriptionBuilder.setIconUri(iconUri); Bundle extras = new Bundle(); extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM); extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM); extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE, MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM); mediaDescriptionBuilder.setExtras(extras); return new MediaBrowser.MediaItem( mediaDescriptionBuilder.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE); }
Grupuj produkty za pomocą wskazówek dotyczących tytułów
Aby pogrupować powiązane elementy multimedialne, musisz używać wskazówek dotyczących poszczególnych elementów. Każdy element multimedialny
w grupie musi zadeklarować w interfejsie MediaDescription
pakiet dodatków,
zawiera mapowanie z kluczem
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE
.
i identyczną wartość ciągu. Zlokalizuj ten ciąg znaków, który jest używany jako
nazwę grupy.
Poniższy fragment kodu pokazuje, jak utworzyć MediaItem
z podgrupą.
nagłówek "Songs"
:
Kotlin
import androidx.media.utils.MediaConstants private fun createMediaItem( mediaId: String, folderName: String, iconUri: Uri ): MediaBrowser.MediaItem { val mediaDescriptionBuilder = MediaDescription.Builder() mediaDescriptionBuilder.setMediaId(mediaId) mediaDescriptionBuilder.setTitle(folderName) mediaDescriptionBuilder.setIconUri(iconUri) val extras = Bundle() extras.putString( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs") mediaDescriptionBuilder.setExtras(extras) return MediaBrowser.MediaItem( mediaDescriptionBuilder.build(), /* playable or browsable flag*/) }
Java
import androidx.media.utils.MediaConstants; private MediaBrowser.MediaItem createMediaItem(String mediaId, String folderName, Uri iconUri) { MediaDescription.Builder mediaDescriptionBuilder = new MediaDescription.Builder(); mediaDescriptionBuilder.setMediaId(mediaId); mediaDescriptionBuilder.setTitle(folderName); mediaDescriptionBuilder.setIconUri(iconUri); Bundle extras = new Bundle(); extras.putString( MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs"); mediaDescriptionBuilder.setExtras(extras); return new MediaBrowser.MediaItem( mediaDescriptionBuilder.build(), /* playable or browsable flag*/); }
Aplikacja musi przekazywać wszystkie elementy multimedialne, które chcesz zgrupować jako sąsiadujące ze sobą bloki. Załóżmy na przykład, że chcesz wyświetlić dwie grupy elementów multimedialnych, „Utwory” i „Albumy”, w tej kolejności, a aplikacja przekazuje pięć elementów multimedialnych w takiej kolejności:
- Element multimedialny A o nazwie
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Element multimedialny B z
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
- Element multimedialny C z
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Element multimedialny D z:
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Element multimedialny E z:
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
Ponieważ elementy multimedialne dla utworu „Utwory” grupa i „Albumy” grupa nie jest zachowywana w ciągłych blokach: Androida Auto i systemu operacyjnego Android Automotive. interpretuje to jako 4 następujące grupy:
- Grupa 1 o nazwie „Utwory” zawierający element multimedialny A
- Grupa 2 o nazwie „Albumy” zawierający element multimedialny B
- Grupa 3 o nazwie „Utwory” z elementami multimedialnymi C i D
- Grupa 4 o nazwie „Albumy” zawierający element multimedialny E
Aby wyświetlić te elementy w 2 grupach, aplikacja musi przekazać te elementy w w tej kolejności:
- Element multimedialny A o nazwie
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Element multimedialny C z
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Element multimedialny D z:
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Element multimedialny B z
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
- Element multimedialny E z:
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
Wyświetlanie dodatkowych wskaźników metadanych
Możesz też dołączyć dodatkowe wskaźniki metadanych, aby ułatwić przegląd informacji informacje o treści w drzewie przeglądarki multimedialnej i podczas odtwarzania. W ciągu przeglądaj drzewo, Android Auto i system operacyjny Android Automotive odczytują powiązane z nim dodatki danego elementu i szukać określonych stałych, by określić, które wskaźniki wyświetlacz. Podczas odtwarzania multimediów Android Auto i system operacyjny Android Automotive odczytują metadanych sesji multimedialnej i określić pewne stałe wskaźników do wyświetlenia.
Tych stałych można używać zarówno w dodatku MediaItem
tekstu, jak i
Dodatki (MediaMetadata
):
EXTRA_DOWNLOAD_STATUS
: wskazuje stan pobierania elementu. Użyj tej stałej jako klucz; możliwe są następujące stałe stałe:STATUS_DOWNLOADED
: element został w całości pobrany.STATUS_DOWNLOADING
: trwa pobieranie elementu.STATUS_NOT_DOWNLOADED
: element nie został pobrany.
METADATA_KEY_IS_EXPLICIT
: wskazuje, czy element zawiera treści dla dorosłych. Aby wskazać, że element jest należy używać tej stałej jako klucza i długiegoMETADATA_VALUE_ATTRIBUTE_PRESENT
.
Te stałe mogą być używane tylko w MediaItem
dodatku tekstu reklamy:
DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS
: wskazuje stan ukończenia długich treści, np. odcinków podcastu, lub audiobooki. Użyj tej stałej jako klucza; następująca liczba całkowita stałe to możliwe wartości:DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_NOT_PLAYED
: element nie został odtworzony.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED
: element został odtworzony częściowo i bieżąca pozycja jest gdzieś pośrodku.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_FULLY_PLAYED
: gdy element jest gotowy.
DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
: wskazuje postęp ukończenia długich filmów jako podwójny od 0,0 do 1,0 włącznie. Sekcja ta zawiera więcej informacji oPARTIALLY_PLAYING
określa, czy Android Auto lub Android Automotive OS wyświetla bardziej znaczący wskaźnik postępu, np. pasek postępu. Jeśli korzystasz z tego dodatkowego miejsca, zapoznaj się z sekcją o Aktualizowanie paska postępu w widoku przeglądania podczas odtwarzania treści w tym przewodniku, aby dowiedzieć się, jak dbać o aktualność wskaźnika po jego pierwszego wyświetlenia.
Aby wyświetlać wskaźniki, które pojawiają się, gdy użytkownik przegląda przeglądanie multimediów
utwórz pakiet dodatków zawierający co najmniej jedną z tych stałych
i przekaż go do metody MediaDescription.Builder.setExtras()
.
Ten fragment kodu pokazuje, jak wyświetlać wskaźniki dotyczące treści dla dorosłych element ukończony w 70%:
Kotlin
import androidx.media.utils.MediaConstants val extras = Bundle() extras.putLong( MediaConstants.METADATA_KEY_IS_EXPLICIT, MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT) extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS, MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED) extras.putDouble( MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.7) val description = MediaDescriptionCompat.Builder() .setMediaId(/*...*/) .setTitle(resources.getString(/*...*/)) .setExtras(extras) .build() return MediaBrowserCompat.MediaItem(description, /* flags */)
Java
import androidx.media.utils.MediaConstants; Bundle extras = new Bundle(); extras.putLong( MediaConstants.METADATA_KEY_IS_EXPLICIT, MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT); extras.putInt( MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS, MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED); extras.putDouble( MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.7); MediaDescriptionCompat description = new MediaDescriptionCompat.Builder() .setMediaId(/*...*/) .setTitle(resources.getString(/*...*/)) .setExtras(extras) .build(); return new MediaBrowserCompat.MediaItem(description, /* flags */);
Aby wyświetlić wskaźniki aktualnie odtwarzanego elementu multimedialnego, możesz:
zadeklaruj wartości Long
dla METADATA_KEY_IS_EXPLICIT
lub EXTRA_DOWNLOAD_STATUS
w MediaMetadataCompat
na mediaSession
. Nie można wyświetlić
DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS
lub
Wskaźniki DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
w widoku odtwarzania.
Poniższy fragment kodu pokazuje, jak wskazać, że bieżący utwór w że widok odtwarzania zawiera treści dla pełnoletnich i pobrane:
Kotlin
import androidx.media.utils.MediaConstants mediaSession.setMetadata( MediaMetadataCompat.Builder() .putString( MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "Song Name") .putString( MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, "Artist name") .putString( MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, albumArtUri.toString()) .putLong( MediaConstants.METADATA_KEY_IS_EXPLICIT, MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT) .putLong( MediaDescriptionCompat.EXTRA_DOWNLOAD_STATUS, MediaDescriptionCompat.STATUS_DOWNLOADED) .build())
Java
import androidx.media.utils.MediaConstants; mediaSession.setMetadata( new MediaMetadataCompat.Builder() .putString( MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "Song Name") .putString( MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, "Artist name") .putString( MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, albumArtUri.toString()) .putLong( MediaConstants.METADATA_KEY_IS_EXPLICIT, MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT) .putLong( MediaDescriptionCompat.EXTRA_DOWNLOAD_STATUS, MediaDescriptionCompat.STATUS_DOWNLOADED) .build());
Aktualizuj pasek postępu w widoku przeglądania podczas odtwarzania treści
Jak już wspomnieliśmy, możesz korzystać z
DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
aby wyświetlić pasek postępu
w przypadku częściowo odtworzonej treści,
widoku przeglądania. Jeśli użytkownik będzie nadal odtwarzać częściowo odtwarzane treści,
z systemu operacyjnego Android Auto lub Android Automotive, ten wskaźnik zmieni się
niedokładne.
Na Androida Auto i Androida Automotive
aby aktualizować pasek postępu, możesz uzupełnić informacje w
MediaMetadataCompat
i PlaybackStateCompat
, aby połączyć bieżące treści
elementów multimedialnych w widoku przeglądania. W przypadku:
element multimedialny, aby miał automatycznie aktualizowany pasek postępu:
- Po utworzeniu
MediaItem
musi wysłaćDESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
. z dodatkami o wartości z zakresu od 0,0 do 1,0 włącznie. MediaMetadataCompat
musi wysłaćMETADATA_KEY_MEDIA_ID
. z wartością ciągu równą identyfikator mediów przekazano doMediaItem
.PlaybackStateCompat
musi zawierać dodatek z kluczemPLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID
. która jest mapowana na wartość ciągu równa się identyfikator mediów przekazano doMediaItem
.
Fragment kodu poniżej pokazuje, jak wskazać, że aktualnie odtwarzany element jest powiązany z elementem w widoku przeglądania:
Kotlin
import androidx.media.utils.MediaConstants // When the MediaItem is constructed to show in the browse view. // Suppose the item was 25% complete when the user launched the browse view. val mediaItemExtras = Bundle() mediaItemExtras.putDouble( MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.25) val description = MediaDescriptionCompat.Builder() .setMediaId("my-media-id") .setExtras(mediaItemExtras) // ...and any other setters. .build() return MediaBrowserCompat.MediaItem(description, /* flags */) // Elsewhere, when the user has selected MediaItem for playback. mediaSession.setMetadata( MediaMetadataCompat.Builder() .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, "my-media-id") // ...and any other setters. .build()) val playbackStateExtras = Bundle() playbackStateExtras.putString( MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID, "my-media-id") mediaSession.setPlaybackState( PlaybackStateCompat.Builder() .setExtras(playbackStateExtras) // ...and any other setters. .build())
Java
import androidx.media.utils.MediaConstants; // When the MediaItem is constructed to show in the browse view. // Suppose the item was 25% complete when the user launched the browse view. Bundle mediaItemExtras = new Bundle(); mediaItemExtras.putDouble( MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.25); MediaDescriptionCompat description = new MediaDescriptionCompat.Builder() .setMediaId("my-media-id") .setExtras(mediaItemExtras) // ...and any other setters. .build(); return MediaBrowserCompat.MediaItem(description, /* flags */); // Elsewhere, when the user has selected MediaItem for playback. mediaSession.setMetadata( new MediaMetadataCompat.Builder() .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, "my-media-id") // ...and any other setters. .build()); Bundle playbackStateExtras = new Bundle(); playbackStateExtras.putString( MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID, "my-media-id"); mediaSession.setPlaybackState( new PlaybackStateCompat.Builder() .setExtras(playbackStateExtras) // ...and any other setters. .build());
Wyświetl możliwe do przeglądania wyniki wyszukiwania
Aplikacja może oferować kontekstowe wyniki wyszukiwania wyświetlane użytkownikom, inicjują zapytanie. Pokaz Androida Auto i Androida Automotive za pomocą interfejsów zapytań lub afordancji, które przestawiają w przypadku zapytań wysłanych wcześniej w tej sesji. Aby dowiedzieć się więcej, przeczytaj Sekcja Obsługa komend głosowych w tym przewodniku.
Aby wyświetlić możliwe do przeglądania wyniki wyszukiwania, dołącz klawisz stały
BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED
w pakiecie dodatkowych usług onGetRoot()
z mapowaniem na wartość logiczną true
.
Ten fragment kodu pokazuje, jak włączyć obsługę w onGetRoot()
:
Kotlin
import androidx.media.utils.MediaConstants @Nullable fun onGetRoot( @NonNull clientPackageName: String, clientUid: Int, @Nullable rootHints: Bundle ): BrowserRoot { val extras = Bundle() extras.putBoolean( MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED, true) return BrowserRoot(ROOT_ID, extras) }
Java
import androidx.media.utils.MediaConstants; @Nullable @Override public BrowserRoot onGetRoot( @NonNull String clientPackageName, int clientUid, @Nullable Bundle rootHints) { Bundle extras = new Bundle(); extras.putBoolean( MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED, true); return new BrowserRoot(ROOT_ID, extras); }
Aby zacząć podawać wyniki wyszukiwania, zastąp onSearch()
w usłudze przeglądarki multimediów. Systemy operacyjne Android Auto i Android Automotive
Przekieruj do tej metody hasła wyszukiwane przez użytkownika za każdym razem, gdy użytkownik wywoła wyszukiwanie
interfejsu zapytań i afordancji „Wyniki wyszukiwania”.
Możesz uporządkować wyszukiwanie
wyników z metody onSearch()
Twojej usługi przy użyciu elementów tytułów
aby użytkownicy mogli je przeglądać. Jeśli na przykład aplikacja odtwarza muzykę, możesz
Porządkuj wyniki wyszukiwania według albumu, wykonawcy i utworu.
Ten fragment kodu pokazuje prostą implementację atrybutu onSearch()
:
Kotlin
fun onSearch(query: String, extras: Bundle) { // Detach from results to unblock the caller (if a search is expensive). result.detach() object:AsyncTask() { internal var searchResponse:ArrayList internal var succeeded = false protected fun doInBackground(vararg params:Void):Void { searchResponse = ArrayList() if (doSearch(query, extras, searchResponse)) { succeeded = true } return null } protected fun onPostExecute(param:Void) { if (succeeded) { // Sending an empty List informs the caller that there were no results. result.sendResult(searchResponse) } else { // This invokes onError() on the search callback. result.sendResult(null) } return null } }.execute() } // Populates resultsToFill with search results. Returns true on success or false on error. private fun doSearch( query: String, extras: Bundle, resultsToFill: ArrayList ): Boolean { // Implement this method. }
Java
@Override public void onSearch(final String query, final Bundle extras, Result<List<MediaItem>> result) { // Detach from results to unblock the caller (if a search is expensive). result.detach(); new AsyncTask<Void, Void, Void>() { List<MediaItem> searchResponse; boolean succeeded = false; @Override protected Void doInBackground(Void... params) { searchResponse = new ArrayList<MediaItem>(); if (doSearch(query, extras, searchResponse)) { succeeded = true; } return null; } @Override protected void onPostExecute(Void param) { if (succeeded) { // Sending an empty List informs the caller that there were no results. result.sendResult(searchResponse); } else { // This invokes onError() on the search callback. result.sendResult(null); } } }.execute() } /** Populates resultsToFill with search results. Returns true on success or false on error. */ private boolean doSearch(String query, Bundle extras, ArrayList<MediaItem> resultsToFill) { // Implement this method. }
Niestandardowe działania przeglądania
Niestandardowe działania przeglądania umożliwiają dodawanie niestandardowych ikon i etykiet do
MediaItem
obiektów w aplikacji do multimediów w samochodzie i obsługa interakcji użytkownika z
tych działań. W ten sposób można rozszerzyć funkcje
na różne sposoby, np. za pomocą funkcji „Pobierz”, „Dodaj do kolejki”, „Włącz radio”
„Ulubione” lub „Usuń” .
Jeśli jest więcej działań niestandardowych niż pozwala na to producent OEM, użytkownik zobaczy rozszerzone menu.
Jak to działa?
Każde niestandardowe działanie przeglądania jest zdefiniowane za pomocą:
- identyfikator działania (unikalny identyfikator w postaci ciągu znaków),
- Etykieta działania (tekst wyświetlany użytkownikowi)
- Identyfikator URI ikony działania (element rysowalny wektorowo, który można zabarwić)
Listę niestandardowych działań przeglądania definiujecie globalnie jako część
BrowseRoot
Następnie możesz dołączyć podzbiór tych działań do poszczególnych kont
MediaItem.
Gdy użytkownik wejdzie w interakcję z niestandardowym działaniem przeglądania, aplikacja otrzyma wywołanie zwrotne
w usłudze onCustomAction()
. Możesz wykonać to działanie i zaktualizować listę
w razie potrzeby – a w razie potrzeby – dla komponentu MediaItem
. Jest to przydatne w przypadku działań stanowych
np. „Ulubione” i „Pobierz”. W przypadku działań, które nie wymagają aktualizacji, np. „Odtwarzanie”
Radio”, nie musisz aktualizować listy działań.
Niestandardowe działania przeglądania możesz też dołączyć do katalogu głównego węzła przeglądania. Te działania wyświetla się na dodatkowym pasku narzędzi pod głównym paskiem narzędzi.
Jak zaimplementować niestandardowe działania przeglądania
Aby dodać do projektu niestandardowe działania przeglądania:
- Zastąp dwie metody w tagu
MediaBrowserServiceCompat
implementacja: - Przeanalizuj limity działań w czasie działania:
- W
onGetRoot()
uzyskaj maksymalną dozwoloną liczbę działań dla każdegoMediaItem
używa kluczaBROWSER_ROOT_HINTS_KEY_CUSTOM_BROWSER_ACTION_LIMIT
. wrootHints
Bundle
. Limit równy 0 oznacza, że cecha jest nieobsługiwane przez system.
- W
- Utwórz globalną listę niestandardowych działań przeglądania:
- Dla każdej czynności utwórz obiekt
Bundle
z tymi kluczami: *EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID
: identyfikator działania *EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL
: etykieta działania *EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI
: identyfikator URI ikony działania * Dodaj do listy wszystkie obiektyBundle
działania.
- Dla każdej czynności utwórz obiekt
- Dodaj listę globalną do
BrowseRoot
:- W sekcji
BrowseRoot
dodatkiBundle
dodaj listę działań jakoParcelable
Arraylist
przy użyciu kluczaBROWSER_SERVICE_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ROOT_LIST
- W sekcji
- Dodaj działania do obiektów
MediaItem
:- Możesz dodawać działania do poszczególnych obiektów
MediaItem
, umieszczając w nich element lista identyfikatorów działań w dodatkachMediaDescriptionCompat
korzystających z kluczaDESCRIPTION_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID_LIST
. Ta lista musi być podzbiorem globalnej listy działań zdefiniowanej przez CiebieBrowseRoot
.
- Możesz dodawać działania do poszczególnych obiektów
- Wykonuj działania i zwracaj postępy lub wyniki:
- W
onCustomAction
wykonaj działanie na podstawie identyfikatora działania i dowolnej wartości inne potrzebne dane. Możesz uzyskać identyfikator elementuMediaItem
, który wywołał działanie z dodatków za pomocą klawiszaEXTRAS_KEY_CUSTOM_BROWSER_ACTION_MEDIA_ITEM_ID
. - Aby zaktualizować listę działań dla elementu
MediaItem
, dodaj parametr klawiszEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
. w toku lub w pakiecie wyników.
- W
Aby rozpocząć, możesz wprowadzić te zmiany w: BrowserServiceCompat
za pomocą niestandardowych działań przeglądania.
Zastąp BrowserServiceCompat
Musisz zastąpić poniższe metody w MediaBrowserServiceCompat
.
public void onLoadItem(String itemId, @NonNull Result<MediaBrowserCompat.MediaItem> result)
public void onCustomAction(@NonNull String action, Bundle extras, @NonNull Result<Bundle> result)
Limit działań analizy
Sprawdź, ile niestandardowych działań przeglądania jest obsługiwanych.
public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, Bundle rootHints) { rootHints.getInt( MediaConstants.BROWSER_ROOT_HINTS_KEY_CUSTOM_BROWSER_ACTION_LIMIT, 0) }
Tworzenie niestandardowego działania przeglądania
Każde działanie musi zostać umieszczone w osobnym pliku Bundle
.
- Identyfikator działania
bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID, "<ACTION_ID>")
- Etykieta działania
bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL, "<ACTION_LABEL>")
- Identyfikator URI ikony działania
bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI, "<ACTION_ICON_URI>")
Dodaj niestandardowe działania przeglądania do kampanii Parceable
ArrayList
Dodaj wszystkie obiekty Bundle
niestandardowej czynności przeglądania do elementu ArrayList
.
private ArrayList<Bundle> createCustomActionsList( CustomBrowseAction browseActions) { ArrayList<Bundle> browseActionsBundle = new ArrayList<>(); for (CustomBrowseAction browseAction : browseActions) { Bundle action = new Bundle(); action.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID, browseAction.mId); action.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL, getString(browseAction.mLabelResId)); action.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI, browseAction.mIcon); browseActionsBundle.add(action); } return browseActionsBundle; }
Dodaj listę niestandardowych działań przeglądania do katalogu głównego przeglądania
public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, Bundle rootHints) { Bundle browserRootExtras = new Bundle(); browserRootExtras.putParcelableArrayList( BROWSER_SERVICE_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ROOT_LIST, createCustomActionsList())); mRoot = new BrowserRoot(ROOT_ID, browserRootExtras); return mRoot; }
Dodaj działania do: MediaItem
MediaDescriptionCompat buildDescription (long id, String title, String subtitle, String description, Uri iconUri, Uri mediaUri, ArrayList<String> browseActionIds) { MediaDescriptionCompat.Builder bob = new MediaDescriptionCompat.Builder(); bob.setMediaId(id); bob.setTitle(title); bob.setSubtitle(subtitle); bob.setDescription(description); bob.setIconUri(iconUri); bob.setMediaUri(mediaUri); Bundle extras = new Bundle(); extras.putStringArrayList( DESCRIPTION_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID_LIST, browseActionIds); bob.setExtras(extras); return bob.build(); } MediaItem mediaItem = new MediaItem(buildDescription(...), flags);
Kompilacja onCustomAction
wyniku
- Analizuj identyfikator mediów z pola
Bundle extras
:@Override public void onCustomAction( @NonNull String action, Bundle extras, @NonNull Result<Bundle> result){ String mediaId = extras.getString(MediaConstans.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_MEDIA_ITEM_ID); }
- W przypadku wyników asynchronicznych odłącz wynik.
result.detach()
- Pakiet wyników kompilacji
- Wiadomość dla użytkownika
mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE, mContext.getString(stringRes))
- Aktualizuj element(służy do aktualizowania działań w elemencie)
mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM, mediaId);
- Otwórz widok odtwarzania
//Shows user the PBV without changing the playback state mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_SHOW_PLAYING_ITEM, null);
- Aktualizowanie węzła przeglądania
//Change current browse node to mediaId mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_BROWSE_NODE, mediaId);
- Wiadomość dla użytkownika
- Jeśli wystąpi błąd, zadzwoń pod numer
result.sendError(resultBundle).
- W przypadku aktualizacji postępu zadzwoń pod numer
result.sendProgressUpdate(resultBundle)
. - Dokończ, dzwoniąc pod numer
result.sendResult(resultBundle)
.
Aktualizowanie stanu działania
Używając metody result.sendProgressUpdate(resultBundle)
z parametrem
EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
.
możesz zaktualizować klucz MediaItem
, aby odzwierciedlić nowy stan działania. Ten
pozwalają przekazywać użytkownikom
informacje o postępach w czasie rzeczywistym
w wyniku ich działań.
Przykład: pobieranie
Oto przykład, w jaki sposób można użyć tej funkcji do implementacji działania pobierania z 3 stanami:
- Pobierz: to jest początkowy stan działania. Gdy użytkownik wybierze
to działanie, możesz zamienić je na „Pobieranie” i zadzwoń
sendProgressUpdate
, aby zaktualizować interfejs użytkownika. - Pobieranie: ten stan oznacza, że trwa pobieranie. Dostępne opcje użyj tego stanu, aby wyświetlić pasek postępu lub inny wskaźnik.
- Pobrano: ten stan oznacza, że pobieranie zostało zakończone. Gdy
Gdy zakończy się pobieranie, możesz zmienić „Pobieranie” opcja „Pobrane”; i zadzwoń
sendResult
zEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
. w celu wskazania, że element powinien zostać odświeżony. Dodatkowo możesz użyćEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE
aby wyświetlić użytkownikowi komunikat o powodzeniu.
Dzięki temu możesz przekazać użytkownikowi jasne informacje na temat pobieranego pliku. a jego obecny stan. Możesz dodać więcej szczegółów za pomocą ikon, które będą wyświetlane 25%, 50%, 75% stanu pobierania.
Przykład: ulubione akcje
Innym przykładem jest ulubione działanie z dwoma stanami:
- Ulubione: to działanie jest wyświetlane przy elementach, które nie znajdują się w
na liście ulubionych użytkowników. Gdy użytkownik wybierze to działanie, możesz je zamienić
z „dodane do ulubionych” i zadzwoń do:
sendResult
, używającEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
. do aktualizacji interfejsu użytkownika. - Dodano do ulubionych: to działanie jest wyświetlane w przypadku elementów, które znajdują się w folderze
listę ulubionych. Gdy użytkownik wybierze to działanie, możesz je zamienić na
„Ulubione” i zadzwoń do:
sendResult
, używającEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
. do aktualizacji interfejsu użytkownika.
Takie podejście zapewnia użytkownikom jasny i spójny sposób zarządzania ulubionych elementów.
Te przykłady pokazują elastyczność niestandardowych działań przeglądania oraz pokazują, jak które pozwalają wdrożyć różne funkcje i uzyskiwać informacje zwrotne w czasie rzeczywistym dla: i zwiększyć wygodę użytkowników w aplikacji do multimediów w samochodzie.
Pełną, przykładową implementację tej funkcji znajdziesz w
TestMediaApp
.
w projekcie.
Włącz sterowanie odtwarzaniem
Android Auto i Android Automotive OS wysyłają polecenia sterowania odtwarzaniem za pomocą
MediaSessionCompat
Twojej usługi.
Musisz zarejestrować sesję i zaimplementować powiązane z nią metody wywołania zwrotnego.
Rejestrowanie sesji multimediów
W usłudze onCreate()
usługi przeglądarki multimediów
utwórz MediaSessionCompat
,
zarejestruj sesję multimediów, wywołując setSessionToken()
.
Ten fragment kodu pokazuje, jak utworzyć i zarejestrować sesję multimediów:
Kotlin
override fun onCreate() { super.onCreate() ... // Start a new MediaSession. val session = MediaSessionCompat(this, "session tag").apply { // Set a callback object that implements MediaSession.Callback // to handle play control requests. setCallback(MyMediaSessionCallback()) } sessionToken = session.sessionToken ... }
Java
public void onCreate() { super.onCreate(); ... // Start a new MediaSession. MediaSessionCompat session = new MediaSessionCompat(this, "session tag"); setSessionToken(session.getSessionToken()); // Set a callback object that implements MediaSession.Callback // to handle play control requests. session.setCallback(new MyMediaSessionCallback()); ... }
Przy tworzeniu obiektu sesji multimediów ustawiasz obiekt wywołania zwrotnego, który jest używany
obsługi żądań sterowania odtwarzaniem. Tworzysz ten obiekt wywołania zwrotnego przez
zapewnia implementację interfejsu MediaSessionCompat.Callback
dla Twojej aplikacji. W następnej sekcji opisujemy, jak wdrożyć ten obiekt.
Wdrażanie poleceń odtwarzania
Gdy użytkownik poprosi o włączenie elementu multimedialnego w aplikacji, Android Automotive
System operacyjny i Android Auto używają interfejsu MediaSessionCompat.Callback
zajęcia z poziomu MediaSessionCompat
w Twojej aplikacji
obiekt uzyskany z przeglądarki multimediów w aplikacji. Gdy użytkownik
chce sterować odtwarzaniem treści, np. wstrzymać odtwarzanie lub przejść do
kolejną ścieżkę, system operacyjny Android Auto i Android Automotive wywołują jedno z wywołań zwrotnych.
za pomocą metod obiektu.
Aby obsługiwać odtwarzanie treści, aplikacja musi obejmować rozszerzenie MediaSessionCompat.Callback
i zaimplementuj metody obsługiwane przez Twoją aplikację.
Wdróż wszystkie poniższe metody wywołania zwrotnego, które mają sens w przypadku typu treści dostępnych w aplikacji:
onPrepare()
- Wywoływana po zmianie źródła multimediów. System operacyjny Android Automotive wywołuje też od razu po uruchomieniu. Aplikacja do multimediów musi zaimplementować tę funkcję .
onPlay()
- Wywoływane, gdy użytkownik zdecyduje się na grę bez wybrania konkretnego przedmiotu. Twoje
musi odtworzyć domyślną treść lub, jeśli odtwarzanie zostało wstrzymane na
onPause()
, Twój wznowi odtwarzanie.Uwaga: aplikacja nie powinna automatycznie rozpoczynać odtwarzania muzyki gdy system operacyjny Android Automotive lub Android Auto połączy się z przeglądarką multimediów. posprzedażna. Więcej informacji można znaleźć w sekcji na temat ustawienie początkowego stanu odtwarzania.
onPlayFromMediaId()
- Wywoływane, gdy użytkownik chce odtworzyć określony element. Metoda jest przekazywana identyfikator przypisany przez usługę przeglądarki multimediów z elementem multimedialnym w hierarchii treści.
onPlayFromSearch()
- Wywoływane, gdy użytkownik chce odtworzyć film z poziomu zapytania. Aplikacja musi: dokonać odpowiedniego wyboru na podstawie przekazanego ciągu wyszukiwania.
onPause()
- Wywoływane, gdy użytkownik wstrzymuje odtwarzanie.
onSkipToNext()
- Wywoływane, gdy użytkownik przejdzie do następnego elementu.
onSkipToPrevious()
- Wywoływane, gdy użytkownik zdecyduje się przejść do poprzedniego elementu.
onStop()
- Wywoływane, gdy użytkownik zatrzymuje odtwarzanie.
Zastąp te metody w aplikacji, aby udostępnić wymagane funkcje. Ty
nie muszą implementować metody, jeśli jej funkcjonalność nie jest obsługiwana przez aplikację. Dla:
np. jeśli aplikacja prowadzi transmisję na żywo (np. transmisję sportową),
nie muszą implementować metody onSkipToNext()
. Możesz użyć domyślnego
implementacji interfejsu onSkipToNext()
.
Aplikacja nie wymaga żadnych specjalnych mechanizmów logicznych do odtwarzania treści głośników. Gdy aplikacja otrzyma prośbę o włączenie treści, może odtworzyć dźwięk. w taki sam sposób, w jaki odtwarza treści z głośników telefonu lub słuchawek dousznych. Systemy operacyjne Android Auto i Android Automotive będzie automatycznie wysyłać treści audio do systemu samochodowego, aby odtwarzać je na na głośnikach samochodu.
Więcej informacji o odtwarzaniu materiałów audio znajdziesz w artykule MediaPlayer – omówienie, Omówienie aplikacji audio, oraz omówieniu odtwarzacza ExoPlayer.
Ustawianie standardowych działań dotyczących odtwarzania
Android Auto i system operacyjny Android Automotive wyświetlają elementy sterujące odtwarzaniem na podstawie
działania włączone w PlaybackStateCompat
obiektu.
Domyślnie aplikacja musi obsługiwać te działania:
Aplikacja może dodatkowo obsługiwać te działania, jeśli dotyczą zawartość aplikacji:
Dodatkowo możesz utworzyć kolejkę odtwarzania, która będzie wyświetlana
użytkownika, ale nie jest to wymagane. Aby to zrobić, wywołaj metodę setQueue()
i setQueueTitle()
włącz ACTION_SKIP_TO_QUEUE_ITEM
i zdefiniuj wywołanie zwrotne onSkipToQueueItem()
.
Dodaliśmy też obsługę ikony Co jest grane, która wskazuje,
aktualnie odtwarzane. Aby to zrobić, wywołaj metodę setActiveQueueItemId()
i przekazuje identyfikator aktualnie odtwarzanego elementu w kolejce. Czynności, które musisz wykonać
aktualizuj aplikację setActiveQueueItemId()
za każdym razem, gdy zmienia się kolejka.
Przyciski wyświetlane w systemie operacyjnym Android Auto i Android Automotive w przypadku każdego włączonego działania
oraz kolejki odtwarzania. Gdy przyciski są
zostanie kliknięty, system wywoła odpowiednie wywołanie zwrotne
MediaSessionCompat.Callback
Zarezerwuj niewykorzystane miejsce
Android Auto i Android Automotive OS rezerwują miejsce w interfejsie na
Działania: ACTION_SKIP_TO_PREVIOUS
i ACTION_SKIP_TO_NEXT
. Jeśli Twoja aplikacja
nie obsługują żadnej z tych funkcji, używają Androida Auto i Androida Automotive
w którym będą wyświetlane
tworzone przez Ciebie działania niestandardowe.
Jeśli nie chcesz wypełniać tych miejsc działaniami niestandardowymi, możesz zarezerwować
aby Android Auto i Android Automotive OS pozostawiły puste miejsce
gdy aplikacja nie obsługuje odpowiedniej funkcji. W tym celu wywołaj
setExtras()
z pakietem dodatków zawierającym stałe odpowiadające argumentowi
zarezerwowane funkcje.
SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_NEXT
odpowiada ACTION_SKIP_TO_NEXT
, a
SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_PREV
odpowiada ACTION_SKIP_TO_PREVIOUS
. Użyj tych stałych jako kluczy
pakietu i jako wartości logicznej używać true
.
Ustaw początkowy stan odtwarzania
Gdy Android Auto i system operacyjny Android Automotive komunikują się z przeglądarką multimediów
, sesja multimediów przekazuje stan odtwarzania treści za pomocą
PlaybackStateCompat
.
Aplikacja nie powinna automatycznie rozpoczynać odtwarzania muzyki, gdy system operacyjny Android Automotive
lub Android Auto i połącz się z przeglądarką multimediów. Zamiast tego zdaj się na Androida
Auto i system operacyjny Android Automotive, aby wznowić lub rozpocząć odtwarzanie na podstawie
czy działania użytkownika.
Aby to zrobić, ustaw początkowy PlaybackStateCompat
Twojej sesji multimedialnej,
STATE_STOPPED
,
STATE_PAUSED
,
STATE_NONE
lub STATE_ERROR
.
Sesje multimedialne w Androidzie Auto i systemie operacyjnym Android Automotive trwają tylko
przez cały czas jego trwania, więc użytkownicy często rozpoczynają i zatrzymują te sesje. Do
ułatwiają płynne przechodzenie między przejazdami i śledzenie poprzednich
stanu sesji. Gdy aplikacja do multimediów otrzyma
użytkownik może automatycznie wznowić pracę od miejsca, w którym ją przerwał
wyłączony – na przykład ostatnio odtwarzany element multimedialny, PlaybackStateCompat
,
i kolejka.
Dodawanie niestandardowych działań związanych z odtwarzaniem
Możesz dodać niestandardowe działania związane z odtwarzaniem, aby wyświetlić dodatkowe działania wykonywane przez
obsługiwane przez aplikację do multimediów. Jeśli pozwala na to miejsce (i nie jest zarezerwowane), Android dodaje komponent
niestandardowe działania do elementów sterujących transportem. W przeciwnym razie działania niestandardowe
wyświetlić w rozszerzonym menu. Działania niestandardowe są wyświetlane w kolejności, w jakiej są wyświetlane
zostaną dodane do PlaybackStateCompat
.
Użyj działań niestandardowych, by zapewnić zachowanie inne niż standardowe działań. Nie zastępuj ani nie powielaj treści standardowych .
Działania niestandardowe możesz dodawać za pomocą interfejsu addCustomAction()
w PlaybackStateCompat.Builder
zajęcia.
Fragment kodu poniżej pokazuje, jak dodać niestandardowy element „Uruchom kanał radiowy” działanie:
Kotlin
stateBuilder.addCustomAction( PlaybackStateCompat.CustomAction.Builder( CUSTOM_ACTION_START_RADIO_FROM_MEDIA, resources.getString(R.string.start_radio_from_media), startRadioFromMediaIcon ).run { setExtras(customActionExtras) build() } )
Java
stateBuilder.addCustomAction( new PlaybackStateCompat.CustomAction.Builder( CUSTOM_ACTION_START_RADIO_FROM_MEDIA, resources.getString(R.string.start_radio_from_media), startRadioFromMediaIcon) .setExtras(customActionExtras) .build());
Bardziej szczegółowy przykład tej metody znajdziesz tutaj: setCustomAction()
w przykładowej aplikacji Universal Android Music Player na GitHubie.
Po utworzeniu działania niestandardowego sesja multimediów może na nie reagować
zastępując onCustomAction()
.
Ten fragment kodu pokazuje, jak aplikacja może reagować na Działanie „Uruchom kanał radiowy”:
Kotlin
override fun onCustomAction(action: String, extras: Bundle?) { when(action) { CUSTOM_ACTION_START_RADIO_FROM_MEDIA -> { ... } } }
Java
@Override public void onCustomAction(@NonNull String action, Bundle extras) { if (CUSTOM_ACTION_START_RADIO_FROM_MEDIA.equals(action)) { ... } }
Bardziej szczegółowy przykład tej metody znajdziesz tutaj: onCustomAction
w przykładowej aplikacji Universal Android Music Player na GitHubie.
Ikony działań niestandardowych
Każde działanie niestandardowe, które tworzysz, wymaga zasobu ikony. Aplikacje w samochodach mogą działają na ekranach o różnych rozmiarach i gęstości, dlatego ikony muszą być obiektami rysowalnymi wektorowo. O obiekt rysowalny wektorowo umożliwia skalowanie zasobów bez utraty szczegółów. Wektor rysowalność ułatwia wyrównywanie krawędzi i rogów z granicami pikseli i mniejszej rozdzielczości.
Jeśli działanie niestandardowe jest stanowe – na przykład powoduje włączenie ustawienia odtwarzania lub wyłączone—udostępnianie różnych ikon dla różnych stanów, zobaczy zmianę, gdy wybierze działanie.
Dodaj alternatywne style ikon dla wyłączonych działań
Jeśli działanie niestandardowe jest niedostępne w bieżącym kontekście, zastąp niestandardową ikonę działania, z ikoną alternatywną, która wskazuje, że działanie jest wyłączona.
Wskaż format audio
Aby wskazać, że aktualnie odtwarzane multimedia używają specjalnego formatu dźwięku:
możesz określić ikony
wyświetlane w samochodach obsługujących tę funkcję. Ty
może ustawić
KEY_CONTENT_FORMAT_TINTABLE_LARGE_ICON_URI
oraz
KEY_CONTENT_FORMAT_TINTABLE_SMALL_ICON_URI
w pakiecie dodatków obecnie odtwarzanego elementu multimedialnego (przekazywanego do
MediaSession.setMetadata()
). Pamiętaj, aby ustawić obie
tych dodatków, aby dostosować je do różnych układów.
Możesz także ustawić dodatkowe pole KEY_IMMERSIVE_AUDIO
aby poinformować
producentów samochodów, że jest to dźwięk absurdalny. Powinni oni być bardzo ostrożni
przy podejmowaniu decyzji, czy zastosować efekty dźwiękowe, które mogą zakłócać
wciągające treści.
Dodaj linki z aktualnie odtwarzanego elementu
Odtwarzany element multimedialny możesz skonfigurować tak, aby jego podtytuł, opis lub oba są linkami do innych elementów multimedialnych. Dzięki temu użytkownik może szybko przejść podobne produkty; na przykład mogą przeskakiwać do innych utworów tego samego wykonawcy, innych odcinków tego podcastu itd. Jeśli samochód obsługuje tę funkcję, może kliknąć link, aby przejść do tych treści.
Aby dodać linki, skonfiguruj
Metadane KEY_SUBTITLE_LINK_MEDIA_ID
(aby dodać link z podtytułu) lub
KEY_DESCRIPTION_LINK_MEDIA_ID
(aby linkować z
opis). Szczegółowe informacje znajdziesz w dokumentacji tych
metadanych.
Obsługa komend głosowych
Aplikacja do multimediów musi obsługiwać komendy głosowe, aby kierowcy mogli i wygodę, która minimalizuje rozpraszanie uwagi. Jeśli na przykład aplikacja odtwarza jeden element multimedialny, użytkownik może powiedzieć „Włącz [tytuł utworu]” i poprosi o włączenie innego utworu bez dotykania wyświetlacz. Użytkownicy mogą inicjować zapytania, klikając odpowiednie przyciski na kierownicą lub słowami-kluczami „OK Google”.
.Gdy Android Auto lub system operacyjny Android Automotive wykryje i zinterpretuje głos,
komenda głosowa jest przesyłana do aplikacji przez
onPlayFromSearch()
Po otrzymaniu tego wywołania zwrotnego aplikacja znajduje treści pasujące do: query
i rozpocznie odtwarzanie.
Użytkownicy mogą w zapytaniu określić różne kategorie haseł: gatunek, wykonawca,
album, tytuł utworu, stację radiową lub playlistę. Podczas tworzenia
obsługi wyszukiwania,
uwzględnij wszystkie kategorie, które mają sens w przypadku Twojej aplikacji.
Jeśli Android Auto lub system operacyjny Android Automotive wykryje, że dane zapytanie pasuje do
dla określonych kategorii, dodaje dodatki w parametrze extras
.
możemy wysłać następujące dodatkowe materiały:
Konto zawiera pusty ciąg tekstowy query
, który może zostać wysłany przez
Android Auto lub system operacyjny Android Automotive, jeśli użytkownik nie określi zapytania.
Na przykład gdy użytkownik powie „Włącz jakąś muzykę”. W takim przypadku aplikacja może
odtworzyć ostatnio odtwarzany lub niedawno sugerowany utwór.
Jeśli wyszukiwanie nie może zostać szybko przetworzone, nie blokuj go w onPlayFromSearch()
.
Zamiast tego ustaw stan odtwarzania na STATE_CONNECTING
i przeprowadzić wyszukiwanie w wątku asynchronicznym.
Po rozpoczęciu odtwarzania możesz wypełnić kolejkę sesji multimediów powiązane treści. Jeśli na przykład użytkownik poprosi o odtworzenie albumu, aplikacja może zapełnić kolejkę listą utworów z albumu. Warto też rozważyć wdrożenie obsługę wyników wyszukiwania, które użytkownik może przeglądać inną ścieżkę pasującą do zapytania.
Oprócz „play” zapytań, systemu operacyjnego Android Auto i Androida Automotive
rozpoznawaj zapytania głosowe, aby sterować odtwarzaniem, np. „wstrzymaj muzykę” i „Dalej
utwór" i dopasujesz te polecenia do odpowiednich wywołań zwrotnych sesji multimediów,
na przykład onPause()
i onSkipToNext()
.
Szczegółowy przykład implementacji komend głosowych w aplikacji, przeczytaj artykuł na temat aplikacji Asystent Google i aplikacje do multimediów.
Stosuj środki ostrożności, które rozpraszają uwagę
Ponieważ podczas korzystania z Androida telefon użytkownika jest połączony z głośnikami samochodu Automatycznie, musisz podjąć dodatkowe środki ostrożności, aby nie rozpraszać uwagi kierowcy.
Wycisz alarmy w samochodzie
Aplikacje do multimediów na Androida Auto nie mogą odtwarzać dźwięku przez głośniki samochodu chyba że użytkownik rozpocznie odtwarzanie, np. naciskając przycisk odtwarzania. Nie może się uruchamiać nawet alarm zaplanowany przez użytkownika z aplikacji do multimediów odtwarzam muzykę przez głośniki w samochodzie.
Aby spełnić to wymaganie,
można użyć: CarConnection
jako sygnału przed odtworzeniem jakiegokolwiek dźwięku. Aplikacja może sprawdzić, czy telefon
wyświetlając obraz na ekranie w samochodzie, obserwując sygnał LiveData
dla połączenia w samochodzie
typ
i sprawdzam, czy jest równy
CONNECTION_TYPE_PROJECTION
Jeśli telefon użytkownika przesyła dźwięk, aplikacje do multimediów, które obsługują alarmy, muszą to robić z następujących elementów:
- Wyłącz alarm.
- Odtwórz alarm na
STREAM_ALARM
i udostępnić na ekranie interfejs do wyłączenia alarmu.
Obsługa reklam medialnych
Domyślnie Android Auto wyświetla powiadomienie o zmianie metadanych multimediów
podczas sesji odtwarzania dźwięku. Gdy aplikacja do multimediów przełącza się z odtwarzania muzyki
do uruchomienia reklamy może rozpraszać uwagę,
powiadomienia. Aby uniemożliwić Androidowi Auto wyświetlanie powiadomień
W takim przypadku musisz ustawić klucz metadanych multimediów
METADATA_KEY_IS_ADVERTISEMENT
do
METADATA_VALUE_ATTRIBUTE_PRESENT
,
Jak widać w tym fragmencie kodu:
Kotlin
import androidx.media.utils.MediaConstants override fun onPlayFromMediaId(mediaId: String, extras: Bundle?) { MediaMetadataCompat.Builder().apply { if (isAd(mediaId)) { putLong( MediaConstants.METADATA_KEY_IS_ADVERTISEMENT, MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT) } // ...add any other properties you normally would. mediaSession.setMetadata(build()) } }
Java
import androidx.media.utils.MediaConstants; @Override public void onPlayFromMediaId(String mediaId, Bundle extras) { MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); if (isAd(mediaId)) { builder.putLong( MediaConstants.METADATA_KEY_IS_ADVERTISEMENT, MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT); } // ...add any other properties you normally would. mediaSession.setMetadata(builder.build()); }
Obsługa błędów ogólnych
Gdy w aplikacji wystąpi błąd, ustaw stan odtwarzania na STATE_ERROR
i podaj komunikat o błędzie, korzystając z setErrorMessage()
. Zobacz PlaybackStateCompat
.
Komunikaty o błędach muszą być widoczne dla użytkownika i zlokalizowane zgodnie z
język. Android Auto i Android Automotive mogą wyświetlać błąd.
wiadomość do użytkownika.
Jeśli na przykład treści nie są dostępne w obecnym regionie użytkownika, możesz
skorzystaj z funkcji ERROR_CODE_NOT_AVAILABLE_IN_REGION
kod błędu podczas ustawiania komunikatu o błędzie.
Kotlin
mediaSession.setPlaybackState( PlaybackStateCompat.Builder() .setState(PlaybackStateCompat.STATE_ERROR) .setErrorMessage(PlaybackStateCompat.ERROR_CODE_NOT_AVAILABLE_IN_REGION, getString(R.string.error_unsupported_region)) // ...and any other setters. .build())
Java
mediaSession.setPlaybackState( new PlaybackStateCompat.Builder() .setState(PlaybackStateCompat.STATE_ERROR) .setErrorMessage(PlaybackStateCompat.ERROR_CODE_NOT_AVAILABLE_IN_REGION, getString(R.string.error_unsupported_region)) // ...and any other setters. .build());
Więcej informacji o stanach błędu znajdziesz w artykule Korzystanie z sesji multimediów: stany i błędy.
Jeśli użytkownik Androida Auto musi otworzyć aplikację na telefonie, aby rozwiązać problem: podać je użytkownikowi w wiadomości. Na przykład: komunikat może brzmieć „Zaloguj się w [nazwa aplikacji]”. zamiast „Zaloguj się”.