Aby używać platformy MediaRouter w aplikacji, musisz pobrać instancję
MediaRouter
i dołącz załącznik
Obiekt MediaRouter.Callback
, który ma nasłuchiwać zdarzeń routingu.
Treści wysyłane trasą multimediów przechodzą przez trasę
powiązane MediaRouteProvider
(z wyjątkiem kilku szczególnych przypadków,
takich jak urządzenie wyjściowe Bluetooth). Rysunek 1 przedstawia ogólny widok
klas używanych do kierowania treści między urządzeniami.
Uwaga: jeśli chcesz, aby aplikacja obsługiwała tę funkcję. urządzeń Google Cast, użyj pakietu Cast SDK i utworzyć aplikację jako nadawca Cast. Postępuj zgodnie ze wskazówkami na Dokumentacja dotycząca przesyłania zamiast bezpośrednio korzystać z platformy MediaRouter.
Przycisk kierowania multimediów
Aplikacje na Androida powinny używać przycisku kierowania multimediów do sterowania routingiem multimediów. Platforma MediaRouter ma standardowy interfejs przycisku, który pomaga użytkownikom rozpoznawać i używać routingu gdy będzie dostępna. Przycisk trasy multimediów jest zwykle umieszczony po prawej stronie na pasku działań aplikacji, tak jak na rys. 2.
Gdy użytkownik naciśnie przycisk kierowania multimediów, na liście pojawią się dostępne trasy multimediów, tak jak na ilustracji 3.
Aby utworzyć przycisk trasy multimediów:
- Używanie klasy AppCompatActivity
- Zdefiniuj element menu przycisku kierowania multimediów
- Tworzenie obiektu MediaRouteSelector
- Dodawanie przycisku trasy multimediów do paska działań
- Tworzenie metod MediaRouter.Callback w cyklu życia aktywności i zarządzanie nimi
W tej sekcji opisano pierwsze cztery kroki. W następnej sekcji opisano metody wywołania zwrotnego.
Używanie klasy AppCompatActivity
Gdy w aktywności używasz platformy routera multimediów, rozszerz ją
aktywność z AppCompatActivity
i zaimportuj
pakiet androidx.appcompat.app
. Musisz dodać parametr
androidx.appcompat:appcompat,
oraz androidx.mediarouter:mediarouter
do obsługi bibliotek
w swoim projekcie programowania aplikacji. Więcej informacji o dodawaniu bibliotek pomocniczych
projektu, zapoznaj się z artykułem Pierwsze kroki z Androidem Jetpack.
Uwaga: pamiętaj, aby użyć androidx
i wdrożyć platformę routera multimediów. Nie używaj starszego pakietu android.media
.
Zdefiniuj element menu przycisku kierowania multimediów
Utwórz plik XML, który definiuje pozycję menu dla przycisku trasy multimediów.
Działaniem elementu powinna być klasa MediaRouteActionProvider
.
Oto przykładowy plik:
// myMediaRouteButtonMenuItem.xml <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" > <item android:id="@+id/media_route_menu_item" android:title="@string/media_route_menu_title" app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider" app:showAsAction="always" /> </menu>
Tworzenie obiektu MediaRouteSelector
Trasy wyświetlane w menu przycisku trasy multimediów są określane przez MediaRouteSelector
.
Przedłuż swoją aktywność od AppCompatActivity
i stworzysz selektor, gdy zostanie utworzona aktywność, wywołując funkcję MediaRouteSelector.Builder
.
z metody onCreate(), jak pokazano na ilustracji
w poniższym przykładowym kodzie. Zwróć uwagę, że selektor jest zapisany w zmiennej klasy, a dozwolone typy tras są określone
dodając MediaControlIntent
obiekty:
Kotlin
class MediaRouterPlaybackActivity : AppCompatActivity() { private var mSelector: MediaRouteSelector? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Create a route selector for the type of routes your app supports. mSelector = MediaRouteSelector.Builder() // These are the framework-supported intents .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) .build() } }
Java
public class MediaRouterPlaybackActivity extends AppCompatActivity { private MediaRouteSelector mSelector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Create a route selector for the type of routes your app supports. mSelector = new MediaRouteSelector.Builder() // These are the framework-supported intents .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) .build(); } }
W większości aplikacji jedyny
wymagany typ trasy to CATEGORY_REMOTE_PLAYBACK
. Ten typ trasy traktuje urządzenie, na którym jest uruchomiona Twoja aplikacja, jak pilota.
Pobieranie, dekodowanie i odtwarzanie wszystkich danych treści odbywa się za pomocą podłączonego urządzenia odbierającego.
Dzięki temu aplikacje obsługujące Google Cast, takie jak
Chromecast – działa.
Kilku producentów obsługuje specjalną opcję routingu z nazwą „wyjściowe dodatkowe”. Przy takim wyznaczaniech tras
aplikacja do multimediów pobiera, renderuje i strumieniowo przesyła filmy bądź muzykę bezpośrednio na ekran lub głośniki na wybranym odbiorniku zdalnym.
Używaj dodatkowych wyjścia do wysyłania treści do bezprzewodowych systemów muzycznych lub wyświetlaczy wideo. Aby umożliwić wykrywanie
dotyczące wyboru tych urządzeń, musisz dodać
CATEGORY_LIVE_AUDIO
lub
CATEGORY_LIVE_VIDEO
steruj kategoriami za pomocą obiektu MediaRouteSelector. Musisz też utworzyć i obsługiwać własne okno Presentation
.
Dodawanie przycisku trasy multimediów do paska działań
Po zdefiniowaniu menu trasy multimediów i zdefiniowania MediaRouteSelector możesz teraz dodać do aktywności przycisk trasy multimediów.
Aby dodać opcje, zastąp metodę onCreateOptionsMenu()
w przypadku każdej aktywności
.
Kotlin
override fun onCreateOptionsMenu(menu: Menu): Boolean { super.onCreateOptionsMenu(menu) // Inflate the menu and configure the media router action provider. menuInflater.inflate(R.menu.sample_media_router_menu, menu) // Attach the MediaRouteSelector to the menu item val mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item) val mediaRouteActionProvider = MenuItemCompat.getActionProvider(mediaRouteMenuItem) as MediaRouteActionProvider // Attach the MediaRouteSelector that you built in onCreate() selector?.also(mediaRouteActionProvider::setRouteSelector) // Return true to show the menu. return true }
Java
@Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); // Inflate the menu and configure the media router action provider. getMenuInflater().inflate(R.menu.sample_media_router_menu, menu); // Attach the MediaRouteSelector to the menu item MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item); MediaRouteActionProvider mediaRouteActionProvider = (MediaRouteActionProvider)MenuItemCompat.getActionProvider( mediaRouteMenuItem); // Attach the MediaRouteSelector that you built in onCreate() mediaRouteActionProvider.setRouteSelector(selector); // Return true to show the menu. return true; }
Więcej informacji o implementowaniu paska działań w aplikacji znajdziesz zobacz pasek działań. przewodnik dla programistów.
Przycisk trasy multimediów możesz też dodać jako obiekt MediaRouteButton
w dowolnym
widok. Element MediaRouteSelector musisz dołączyć do przycisku za pomocą metody setRouteSelector()
. Zobacz
Lista kontrolna do projektowania w Google Cast
.
Wywołania zwrotne MediaRouter
Wszystkie aplikacje uruchomione na tym samym urządzeniu korzystają z jednej instancji MediaRouter
i jej tras
(filtrowane według aplikacji według parametru MediaRouteSelector). Każde działanie komunikuje się z MediaRouter
przy użyciu własnej implementacji obiektu MediaRouter.Callback
. MediaRouter wywołuje metody wywołania zwrotnego za każdym razem, gdy użytkownik wybierze, zmieni lub rozłączy trasę.
Wywołanie zwrotne zawiera kilka metod, które możesz zastąpić, aby uzyskać informacje o
zdarzeń routingu. Implementacja klasy MediaRouter.Callback
powinna przynajmniej zastąpić
onRouteSelected()
i
onRouteUnselected()
Ponieważ MediaRouter jest zasobem udostępnionym, aplikacja musi zarządzać wywołaniami zwrotnymi MediaRouter w odpowiedzi na typowe wywołania zwrotne cyklu życia aktywności:
- Po utworzeniu aktywności (
onCreate(Bundle)
) użyj wskaźnikaMediaRouter
i przytrzymaj go przez cały okres istnienia aplikacji. - Dołączaj wywołania zwrotne do MediaRouter, gdy aktywność staje się widoczna (
onStart()
) i odłączaj je, gdy jest ukryta (onStop()
).
Następujący przykładowy kod pokazuje, jak
jak utworzyć i zapisać obiekt wywołania zwrotnego,
uzyskać instancję MediaRouter
i zarządzać wywołaniami zwrotnymi.
Zwróć uwagę na użycie flagi CALLBACK_FLAG_REQUEST_DISCOVERY
podczas dołączania wywołań zwrotnych w onStart()
.
Dzięki temu element MediaRouteSelector będzie odświeżać przycisk trasy multimediów
z listą dostępnych tras.
Kotlin
class MediaRouterPlaybackActivity : AppCompatActivity() { private var mediaRouter: MediaRouter? = null private var mSelector: MediaRouteSelector? = null // Variables to hold the currently selected route and its playback client private var mRoute: MediaRouter.RouteInfo? = null private var remotePlaybackClient: RemotePlaybackClient? = null // Define the Callback object and its methods, save the object in a class variable private val mediaRouterCallback = object : MediaRouter.Callback() { override fun onRouteSelected(router: MediaRouter, route: MediaRouter.RouteInfo) { Log.d(TAG, "onRouteSelected: route=$route") if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { // Stop local playback (if necessary) // ... // Save the new route mRoute = route // Attach a new playback client remotePlaybackClient = RemotePlaybackClient(this@MediaRouterPlaybackActivity, mRoute) // Start remote playback (if necessary) // ... } } override fun onRouteUnselected( router: MediaRouter, route: MediaRouter.RouteInfo, reason: Int ) { Log.d(TAG, "onRouteUnselected: route=$route") if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { // Changed route: tear down previous client mRoute?.also { remotePlaybackClient?.release() remotePlaybackClient = null } // Save the new route mRoute = route when (reason) { MediaRouter.UNSELECT_REASON_ROUTE_CHANGED -> { // Resume local playback (if necessary) // ... } } } } } // Retain a pointer to the MediaRouter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Get the media router service. mediaRouter = MediaRouter.getInstance(this) ... } // Use this callback to run your MediaRouteSelector to generate the // list of available media routes override fun onStart() { mSelector?.also { selector -> mediaRouter?.addCallback(selector, mediaRouterCallback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY) } super.onStart() } // Remove the selector on stop to tell the media router that it no longer // needs to discover routes for your app. override fun onStop() { mediaRouter?.removeCallback(mediaRouterCallback) super.onStop() } ... }
Java
public class MediaRouterPlaybackActivity extends AppCompatActivity { private MediaRouter mediaRouter; private MediaRouteSelector mSelector; // Variables to hold the currently selected route and its playback client private MediaRouter.RouteInfo mRoute; private RemotePlaybackClient remotePlaybackClient; // Define the Callback object and its methods, save the object in a class variable private final MediaRouter.Callback mediaRouterCallback = new MediaRouter.Callback() { @Override public void onRouteSelected(MediaRouter router, RouteInfo route) { Log.d(TAG, "onRouteSelected: route=" + route); if (route.supportsControlCategory( MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){ // Stop local playback (if necessary) // ... // Save the new route mRoute = route; // Attach a new playback client remotePlaybackClient = new RemotePlaybackClient(this, mRoute); // Start remote playback (if necessary) // ... } } @Override public void onRouteUnselected(MediaRouter router, RouteInfo route, int reason) { Log.d(TAG, "onRouteUnselected: route=" + route); if (route.supportsControlCategory( MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){ // Changed route: tear down previous client if (mRoute != null && remotePlaybackClient != null) { remotePlaybackClient.release(); remotePlaybackClient = null; } // Save the new route mRoute = route; if (reason != MediaRouter.UNSELECT_REASON_ROUTE_CHANGED) { // Resume local playback (if necessary) // ... } } } } // Retain a pointer to the MediaRouter @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Get the media router service. mediaRouter = MediaRouter.getInstance(this); ... } // Use this callback to run your MediaRouteSelector to generate the list of available media routes @Override public void onStart() { mediaRouter.addCallback(mSelector, mediaRouterCallback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY); super.onStart(); } // Remove the selector on stop to tell the media router that it no longer // needs to discover routes for your app. @Override public void onStop() { mediaRouter.removeCallback(mediaRouterCallback); super.onStop(); } ... }
Platforma routera multimediów też zapewnia
MediaRouteDiscoveryFragment
klasa, która obsługuje dodawanie i
przez usunięcie wywołania zwrotnego dla aktywności.
Uwaga: jeśli tworzysz aplikację do odtwarzania muzyki i chcesz, aby była ona włączona
muzyki, gdy jest odtwarzana w tle, do jej odtwarzania musisz utworzyć pakiet Service
i wywołaj platformę routera multimediów z wywołań zwrotnych cyklu życia usługi.
Sterowanie trasą odtwarzania zdalnego
Gdy wybierzesz trasę zdalnego odtwarzania, aplikacja będzie działać jak pilot. urządzenie na drugim końcu trasy,
obsługuje wszystkie funkcje pobierania, dekodowania i odtwarzania danych treści. Elementy sterujące w interfejsie aplikacji komunikują się z urządzeniem odbierającym za pomocą
RemotePlaybackClient
obiekt.
Klasa RemotePlaybackClient
udostępnia dodatkowe metody
do zarządzania odtwarzaniem treści. Oto kilka najważniejszych metod odtwarzania z klasy RemotePlaybackClient
:
play()
– odtwórz określony utwór plik multimedialny określony przez parametrUri
.pause()
– wstrzymaj odtwarzanej ścieżki multimedialnej.resume()
– kontynuuj odtwarzanie bieżącego utworu po użyciu polecenia wstrzymania.seek()
– przenieś do określonego miejsca pozycji w bieżącej ścieżce.release()
– zdemontuj połączenia między aplikacją a zdalnym urządzeniem odtwarzającym.
Korzystając z tych metod, możesz dołączać działania do elementów sterujących odtwarzaniem, które podasz na swoim . Większość z tych metod pozwala też dołączyć obiekt wywołania zwrotnego, aby można było monitorować postęp zadania odtwarzania lub żądania sterowania.
Klasa RemotePlaybackClient
obsługuje również kolejkowanie
wiele elementów multimedialnych do odtwarzania i zarządzania kolejką multimediów.
Kod demonstracyjny
Android BasicMediaRouter i MediaRouter Przykłady dokładniej pokazują wykorzystanie interfejsu MediaRouter API.