Platforma routera multimedialnego w Androidzie umożliwia producentom odtwarzanie treści na urządzeniach.
za pomocą standaryzowanego interfejsu o nazwie MediaRouteProvider
.
Dostawca trasy definiuje wspólny interfejs do odtwarzania multimediów na urządzeniu odbiornika,
możliwość odtwarzania multimediów na sprzęcie z dowolnej aplikacji na Androida, która obsługuje multimedia
trasy.
Z tego przewodnika dowiesz się, jak utworzyć dostawcę tras multimediów dla urządzenia odbiornika
w innych aplikacjach
do odtwarzania multimediów na Androidzie. Aby korzystać z tego interfejsu API,
musisz znać najważniejsze klasy
MediaRouteProvider
MediaRouteProviderDescriptor
i
RouteController
.
Omówienie
Platforma routera multimedialnego na Androida umożliwia programistom aplikacji do multimediów i urządzeniom do odtwarzania multimediów
producentom możliwość łączenia się za pomocą wspólnego interfejsu API i wspólnego interfejsu użytkownika. Deweloperzy aplikacji, którzy
zaimplementuj interfejs MediaRouter
, będzie mógł łączyć się z
platformy i odtwarzania treści na urządzeniach, które działają w ramach platformy routera multimediów. Multimedia
producenci urządzeń odtwarzających mogą korzystać z platformy, publikując MediaRouteProvider
, który umożliwia innym aplikacjom nawiązywanie połączeń
na urządzeniach odbioru. Rysunek 1 pokazuje, jak aplikacja łączy się z punktem odbierającym
za pomocą platformy routera multimediów.
![](https://developer.android.google.cn/static/images/mediarouter/media-route-provider-framework.png?authuser=0000&hl=pl)
Rysunek 1. Omówienie sposobu, w jaki klasy dostawców tras mediów zapewniają komunikację z aplikacji do multimediów na urządzenie odbiornika.
Gdy utworzysz dostawcę tras multimediów dla urządzenia odbiornika, będzie on udostępniał w następujących celach:
- Opisz i opublikuj możliwości urządzenia odbierającego, aby mogły je wykryć inne aplikacje i używać funkcji odtwarzania.
- Opakuj interfejs programowania urządzenia odbierającego i jego komunikację z mechanizmów transportowych zapewniających zgodność urządzenia z platformą routera multimediów.
Rozłożenie dostawców tras
Dostawca tras multimediów jest rozpowszechniany jako część aplikacji na Androida. Twoim dostawcą tras może być
udostępniane innym aplikacjom przez rozszerzenie
MediaRouteProviderService
lub opakowanie implementacji
MediaRouteProvider
z własną usługą i zadeklarowanie zamiaru użytkownika
dla dostawcy kierowania multimediów. Te czynności pozwalają innym aplikacjom wykryć i wykorzystać
zgodnie z przepisami
dotyczącymi multimediów.
Uwaga: aplikacja zawierająca dostawcę trasy multimediów może też zawierać element Interfejs MediaRouter do dostawcy trasy, ale nie jest to wymagane.
Biblioteka pomocy MediaRouter
Interfejsy API routerów multimediów są zdefiniowane w sekcji Biblioteka MediaRouter na AndroidaX Musisz dodać tę bibliotekę do projektu deweloperskiego aplikacji. Więcej informacji o dodawaniu bibliotek pomocy do projektu, zobacz Konfigurowanie biblioteki pomocy.
Uwaga: pamiętaj, aby użyć AndroidX
i wdrożyć platformę routera multimediów.
Nie używaj starszego pakietu android.media
.
Tworzenie usługi dostawcy
Platforma routera multimediów musi mieć możliwość wykrycia dostawcy tras multimediów i połączenia się z nim
, aby umożliwić innym aplikacjom korzystanie z Twojej trasy. W tym celu platforma routera multimediów
wyszukuje aplikacje deklarujące działanie intencji dostawcy trasy multimediów. Gdy inna aplikacja chce
połączyć się z dostawcą, platforma musi mieć możliwość jej wywoływania i łączenia się z nią. Dzięki temu dostawca
musi być zawarta w elemencie Service
.
Ten przykładowy kod przedstawia deklarację usługi dostawcy tras multimediów oraz filtr intencji w pliku manifestu, który umożliwia jego wykrywanie i używanie przez router multimediów platforma:
<service android:name=".provider.SampleMediaRouteProviderService" android:label="@string/sample_media_route_provider_service" android:process=":mrp"> <intent-filter> <action android:name="android.media.MediaRouteProviderService" /> </intent-filter> </service>
Ten przykładowy plik manifestu deklaruje usługę, która opakowuje rzeczywiste klasy dostawcy trasy multimediów.
Platforma routera multimediów na Androida zapewnia
Klasa MediaRouteProviderService
do użycia jako kod usługi dla
dostawców tras multimediów. Ten przykładowy kod pokazuje, jak używać tego opakowania
zajęcia:
Kotlin
class SampleMediaRouteProviderService : MediaRouteProviderService() { override fun onCreateMediaRouteProvider(): MediaRouteProvider { return SampleMediaRouteProvider(this) } }
Java
public class SampleMediaRouteProviderService extends MediaRouteProviderService { @Override public MediaRouteProvider onCreateMediaRouteProvider() { return new SampleMediaRouteProvider(this); } }
Określanie możliwości tras
Aplikacje łączące się z platformą routera multimediów mogą wykryć trasę multimediów przez z pliku manifestu aplikacji, ale muszą też znać możliwości tras multimediów które dostarczą. Trasy multimediów mogą być różnego rodzaju i mają odmienne funkcje. Mogą też mieć inne aplikacje musisz mieć możliwość wykrycia tych danych, aby określić, czy są one zgodne z Twoją trasą.
Platforma routera multimediów umożliwia definiowanie i publikowanie możliwości mediów
trasa przez obiekty IntentFilter
, MediaRouteDescriptor
i MediaRouteProviderDescriptor
. W tej sekcji wyjaśniamy, jak ich używać
na potrzeby publikowania szczegółów trasy multimediów w innych aplikacjach.
Kategorie tras
W automatycznym opisie dostawcy trasy multimediów musisz określić czy Twój dostawca obsługuje odtwarzanie zdalne, dodatkowe wyjście czy oba te tryby. Oto trasa kategorie udostępniane przez platformę Media Router:
CATEGORY_LIVE_AUDIO
– wyjście audio do dodatkowego urządzenia wyjściowego, np. bezprzewodowego systemu muzycznego.CATEGORY_LIVE_VIDEO
– Wyjście wideo do dodatkowego urządzenia wyjściowego, np. wyświetlacza bezprzewodowego.CATEGORY_REMOTE_PLAYBACK
– odtwarzaj filmy lub dźwięk na innym urządzeniu, które obsługuje multimedia pobieranie, dekodowanie i odtwarzanie, na przykład Urządzeń Chromecast.
Aby dodać te ustawienia do opisu trasy multimediów, musisz wstawić je w polu
obiekt IntentFilter
, który dodasz później do
Obiekt MediaRouteDescriptor
:
Kotlin
class SampleMediaRouteProvider(context: Context) : MediaRouteProvider(context) { companion object { private val CONTROL_FILTERS_BASIC: ArrayList<IntentFilter> = IntentFilter().run { addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) arrayListOf(this) } } }
Java
public final class SampleMediaRouteProvider extends MediaRouteProvider { private static final ArrayList<IntentFilter> CONTROL_FILTERS_BASIC; static { IntentFilter videoPlayback = new IntentFilter(); videoPlayback.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); CONTROL_FILTERS_BASIC = new ArrayList<IntentFilter>(); CONTROL_FILTERS_BASIC.add(videoPlayback); } }
Jeśli określisz intencję CATEGORY_REMOTE_PLAYBACK
, musisz też zdefiniować typy mediów
elementy sterujące odtwarzaniem są obsługiwane przez Twojego dostawcę tras multimediów. W następnej sekcji dowiesz się, jak
określić te ustawienia dla urządzenia.
Typy multimediów i protokoły
Dostawca kierowania multimediów dla zdalnego urządzenia odtwarzania musi określić typy multimediów i przenoszenie
obsługiwanych protokołów. Te ustawienia określa się za pomocą funkcji IntentFilter
i addDataScheme()
oraz
addDataType()
metod tego obiektu.
ten fragment kodu pokazuje, jak zdefiniować filtr intencji na potrzeby obsługi filmów zdalnych
przy użyciu protokołów http, https i protokołu Realtime Streaming Protocol (RTSP):
Kotlin
class SampleMediaRouteProvider(context: Context) : MediaRouteProvider(context) { companion object { private fun IntentFilter.addDataTypeUnchecked(type: String) { try { addDataType(type) } catch (ex: IntentFilter.MalformedMimeTypeException) { throw RuntimeException(ex) } } private val CONTROL_FILTERS_BASIC: ArrayList<IntentFilter> = IntentFilter().run { addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) addAction(MediaControlIntent.ACTION_PLAY) addDataScheme("http") addDataScheme("https") addDataScheme("rtsp") addDataTypeUnchecked("video/*") arrayListOf(this) } } ... }
Java
public final class SampleMediaRouteProvider extends MediaRouteProvider { private static final ArrayList<IntentFilter> CONTROL_FILTERS_BASIC; static { IntentFilter videoPlayback = new IntentFilter(); videoPlayback.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); videoPlayback.addAction(MediaControlIntent.ACTION_PLAY); videoPlayback.addDataScheme("http"); videoPlayback.addDataScheme("https"); videoPlayback.addDataScheme("rtsp"); addDataTypeUnchecked(videoPlayback, "video/*"); CONTROL_FILTERS_BASIC = new ArrayList<IntentFilter>(); CONTROL_FILTERS_BASIC.add(videoPlayback); } ... private static void addDataTypeUnchecked(IntentFilter filter, String type) { try { filter.addDataType(type); } catch (MalformedMimeTypeException ex) { throw new RuntimeException(ex); } } }
Sterowanie odtwarzaniem
Dostawca tras multimediów, który oferuje zdalne odtwarzanie, musi określić typy elementów sterujących multimediami który obsługuje. Oto ogólne rodzaje ustawień zapewnianych przez trasy multimediów:
- Elementy sterujące odtwarzaniem, takie jak odtwarzanie, wstrzymywanie, przewijanie do tyłu i do przodu.
- funkcje kolejki umożliwiające aplikacji wysyłającej dodawanie i usuwanie elementów; z playlisty przechowywanej przez urządzenie odbierające.
- funkcje sesji, które uniemożliwiają wysyłanie aplikacji i nie zakłócają działania Jeśli urządzenie odbierające poda identyfikator sesji aplikacji wysyłającej żądanie, a następnie identyfikator ten przy każdym kolejnym żądaniu elementu sterującego odtwarzaniem.
Poniższy przykładowy kod pokazuje, jak utworzyć filtr intencji do obsługi funkcji podstawowe sterowanie odtwarzaniem multimediów:
Kotlin
class SampleMediaRouteProvider(context: Context) : MediaRouteProvider(context) { companion object { ... private val CONTROL_FILTERS_BASIC: ArrayList<IntentFilter> = run { val videoPlayback: IntentFilter = ... ... val playControls = IntentFilter().apply { addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) addAction(MediaControlIntent.ACTION_SEEK) addAction(MediaControlIntent.ACTION_GET_STATUS) addAction(MediaControlIntent.ACTION_PAUSE) addAction(MediaControlIntent.ACTION_RESUME) addAction(MediaControlIntent.ACTION_STOP) } arrayListOf(videoPlayback, playControls) } } ... }
Java
public final class SampleMediaRouteProvider extends MediaRouteProvider { private static final ArrayList<IntentFilter> CONTROL_FILTERS_BASIC; static { ... IntentFilter playControls = new IntentFilter(); playControls.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); playControls.addAction(MediaControlIntent.ACTION_SEEK); playControls.addAction(MediaControlIntent.ACTION_GET_STATUS); playControls.addAction(MediaControlIntent.ACTION_PAUSE); playControls.addAction(MediaControlIntent.ACTION_RESUME); playControls.addAction(MediaControlIntent.ACTION_STOP); CONTROL_FILTERS_BASIC = new ArrayList<IntentFilter>(); CONTROL_FILTERS_BASIC.add(videoPlayback); CONTROL_FILTERS_BASIC.add(playControls); } ... }
Więcej informacji o dostępnych intencjach sterowania odtwarzaniem znajdziesz w
MediaControlIntent
zajęcia.
Deskryptor MediaRouteProvider
Po zdefiniowaniu możliwości trasy multimediów za pomocą obiektów IntentFilter
możesz utworzyć obiekt deskryptora do opublikowania
routera multimedialnego w Androidzie. Ten obiekt deskryptora zawiera specyfikę Twoich multimediów
dzięki funkcji tras, dzięki którym inne aplikacje mogą określić sposób interakcji z multimediami
.
Ten przykładowy kod pokazuje, jak dodać wcześniej utworzone filtry intencji do
MediaRouteProviderDescriptor
i ustaw deskryptor do użycia przez
platforma routera multimediów:
Kotlin
class SampleMediaRouteProvider(context: Context) : MediaRouteProvider(context) { init { publishRoutes() } private fun publishRoutes() { val resources = context.resources val routeName: String = resources.getString(R.string.variable_volume_basic_route_name) val routeDescription: String = resources.getString(R.string.sample_route_description) // Create a route descriptor using previously created IntentFilters val routeDescriptor: MediaRouteDescriptor = MediaRouteDescriptor.Builder(VARIABLE_VOLUME_BASIC_ROUTE_ID, routeName) .setDescription(routeDescription) .addControlFilters(CONTROL_FILTERS_BASIC) .setPlaybackStream(AudioManager.STREAM_MUSIC) .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE) .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE) .setVolumeMax(VOLUME_MAX) .setVolume(mVolume) .build() // Add the route descriptor to the provider descriptor val providerDescriptor: MediaRouteProviderDescriptor = MediaRouteProviderDescriptor.Builder() .addRoute(routeDescriptor) .build() // Publish the descriptor to the framework descriptor = providerDescriptor } ... }
Java
public SampleMediaRouteProvider(Context context) { super(context); publishRoutes(); } private void publishRoutes() { Resources r = getContext().getResources(); // Create a route descriptor using previously created IntentFilters MediaRouteDescriptor routeDescriptor = new MediaRouteDescriptor.Builder( VARIABLE_VOLUME_BASIC_ROUTE_ID, r.getString(R.string.variable_volume_basic_route_name)) .setDescription(r.getString(R.string.sample_route_description)) .addControlFilters(CONTROL_FILTERS_BASIC) .setPlaybackStream(AudioManager.STREAM_MUSIC) .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE) .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE) .setVolumeMax(VOLUME_MAX) .setVolume(mVolume) .build(); // Add the route descriptor to the provider descriptor MediaRouteProviderDescriptor providerDescriptor = new MediaRouteProviderDescriptor.Builder() .addRoute(routeDescriptor) .build(); // Publish the descriptor to the framework setDescriptor(providerDescriptor); }
Więcej informacji o dostępnych ustawieniach deskryptora znajdziesz w dokumentacji
dla MediaRouteDescriptor
i MediaRouteProviderDescriptor
.
Sterowanie trasami
Gdy aplikacja łączy się z dostawcą tras multimediów, dostawca odbiera odtwarzanie
za pomocą platformy routera multimediów wysyłanych do Twojej trasy przez inne aplikacje. Aby rozwiązać ten problem:
żądań, musisz udostępnić implementację klasy MediaRouteProvider.RouteController
, która przetwarza polecenia
i obsługuje faktyczną komunikację z urządzeniem odbierającym.
Platforma routera multimediów wywołuje onCreateRouteController()
dostawcy tras, aby uzyskać instancję tej klasy, a następnie kierować do niej żądania.
Oto kluczowe metody klasy MediaRouteProvider.RouteController
, które musisz zaimplementować w przypadku
Twój dostawca tras multimediów:
onSelect()
– Wywoływane, gdy aplikacja wybiera trasę do odtwarzania. Używasz tej metody do: wszelkie prace przygotowawcze, które mogą być wymagane przed rozpoczęciem odtwarzania multimediów.onControlRequest()
– wysyła określone polecenia dotyczące odtwarzania do urządzenia odbierającego.onSetVolume()
– wysyła do urządzenia odbierającego żądanie ustawienia głośności odtwarzania na dla konkretnej wartości.onUpdateVolume()
– wysyła żądanie do urządzenia odbierającego, aby zmodyfikować odtwarzanie o określoną ilość.onUnselect()
– wywoływane, gdy aplikacja odznacza trasę.onRelease()
– wywoływane, gdy trasa nie jest już potrzebna przez platformę, dzięki czemu może i zasobami Google Cloud.
Wszystkie żądania dotyczące sterowania odtwarzaniem (oprócz zmiany głośności) są kierowane do onControlRequest()
. Twoja implementacja tej metody musi przeanalizować żądania kontrolne i na nie odpowiedzieć
w odpowiedni sposób. Oto przykładowa implementacja tej metody, która przetwarza polecenia dla
trasa do zdalnego odtwarzania multimediów:
Kotlin
private class SampleRouteController : MediaRouteProvider.RouteController() { ... override fun onControlRequest( intent: Intent, callback: MediaRouter.ControlRequestCallback? ): Boolean { return if (intent.hasCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { val action = intent.action when (action) { MediaControlIntent.ACTION_PLAY -> handlePlay(intent, callback) MediaControlIntent.ACTION_ENQUEUE -> handleEnqueue(intent, callback) MediaControlIntent.ACTION_REMOVE -> handleRemove(intent, callback) MediaControlIntent.ACTION_SEEK -> handleSeek(intent, callback) MediaControlIntent.ACTION_GET_STATUS -> handleGetStatus(intent, callback) MediaControlIntent.ACTION_PAUSE -> handlePause(intent, callback) MediaControlIntent.ACTION_RESUME -> handleResume(intent, callback) MediaControlIntent.ACTION_STOP -> handleStop(intent, callback) MediaControlIntent.ACTION_START_SESSION -> handleStartSession(intent, callback) MediaControlIntent.ACTION_GET_SESSION_STATUS -> handleGetSessionStatus(intent, callback) MediaControlIntent.ACTION_END_SESSION -> handleEndSession(intent, callback) else -> false }.also { Log.d(TAG, sessionManager.toString()) } } else { false } } ... }
Java
private final class SampleRouteController extends MediaRouteProvider.RouteController { ... @Override public boolean onControlRequest(Intent intent, ControlRequestCallback callback) { String action = intent.getAction(); if (intent.hasCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { boolean success = false; if (action.equals(MediaControlIntent.ACTION_PLAY)) { success = handlePlay(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_ENQUEUE)) { success = handleEnqueue(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_REMOVE)) { success = handleRemove(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_SEEK)) { success = handleSeek(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_GET_STATUS)) { success = handleGetStatus(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_PAUSE)) { success = handlePause(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_RESUME)) { success = handleResume(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_STOP)) { success = handleStop(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_START_SESSION)) { success = handleStartSession(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_GET_SESSION_STATUS)) { success = handleGetSessionStatus(intent, callback); } else if (action.equals(MediaControlIntent.ACTION_END_SESSION)) { success = handleEndSession(intent, callback); } Log.d(TAG, sessionManager.toString()); return success; } return false; } ... }
Pamiętaj, że klasa MediaRouteProvider.RouteController
ma działać jako kod
dla interfejsu API
do sprzętu do odtwarzania multimediów. Implementacja metod w tej klasie jest
całkowicie zależy od interfejsu programowego udostępnianego przez urządzenie odbierające.
Kod demonstracyjny
MediaRouter Przykład pokazuje, jak utworzyć dostawcę niestandardowego trasy multimediów.