MediaRouter – Übersicht

Damit Sie das MediaRouter-Framework in Ihrer App verwenden können, benötigen Sie eine Instanz. des MediaRouter-Objekts und fügen Sie ein MediaRouter.Callback-Objekt, um auf Routingereignisse zu warten. Inhalte, die über eine Medienroute gesendet werden, durchlaufen die MediaRouteProvider verknüpft (außer in einigen Sonderfällen, wie ein Bluetooth-Ausgabegerät). Abbildung 1 bietet einen allgemeinen Überblick über Klassen zum Weiterleiten von Inhalten zwischen Geräten.

Abbildung 1: Übersicht über die wichtigsten von Apps verwendeten Media Router-Klassen

Hinweis:Wenn Sie möchten, dass Ihre App Google Cast-Geräte, sollten Sie das Cast SDK verwenden, und erstelle deine App als Cast-Sender. Folgen Sie der Anleitung in der Cast-Dokumentation anstatt das MediaRouter-Framework direkt zu verwenden.

Schaltfläche „Medienroute“

In Android-Apps sollte eine Schaltfläche für die Medienweiterleitung verwendet werden. MediaRouter-Framework bietet eine Standardoberfläche für die Schaltfläche, über die Nutzer das Routing erkennen und verwenden können sobald er verfügbar ist. Die Schaltfläche für die Medienroute befindet sich normalerweise rechts auf dem in die Aktionsleiste Ihrer App ein, wie in Abbildung 2 dargestellt.

Abbildung 2: Schaltfläche „Medienroute“ in der Aktionsleiste.

Wenn der Nutzer auf die Schaltfläche für die Medienroute drückt, werden die verfügbaren Medienrouten in einer Liste angezeigt (siehe Abbildung 3).

Abbildung 3: Eine Liste der verfügbaren Medienrouten, die nach dem Drücken der Schaltfläche für die Medienroute angezeigt wird.

So erstellen Sie eine Schaltfläche für die Medienroute:

  1. AppCompatActivity verwenden
  2. Menüelement für die Schaltfläche „Medienroute“ definieren
  3. MediaRouteSelector erstellen
  4. Schaltfläche für Medienroute zur Aktionsleiste hinzufügen
  5. MediaRouter.Callback-Methoden im Lebenszyklus Ihrer Aktivität erstellen und verwalten

In diesem Abschnitt werden die ersten vier Schritte beschrieben. Im nächsten Abschnitt werden die Callback-Methoden beschrieben.

AppCompatActivity verwenden

Wenn Sie das Media Router-Framework in einer Aktivität verwenden, sollten Sie die Aktivität aus AppCompatActivity und importieren Sie den Paket androidx.appcompat.app. Sie müssen den Parameter androidx.appcompat:appcompat und androidx.mediarouter:mediarouter Supportbibliotheken für Ihr App-Entwicklungsprojekt. Weitere Informationen zum Hinzufügen von Supportbibliotheken erhalten Sie unter Erste Schritte mit Android Jetpack.

Achtung: Verwenden Sie auf jeden Fall die Methode androidx. Implementierung des Media Router-Frameworks. Verwende nicht das ältere android.media-Paket.

Erstellen Sie eine XML-Datei, die einen Menüpunkt für die Medienroute-Schaltfläche definiert. Die Aktion des Elements sollte die Klasse MediaRouteActionProvider sein. Hier ist eine Beispieldatei:

// 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>

MediaRouteSelector erstellen

Die Routen, die im Menü der Schaltfläche für Medienrouten angezeigt werden, werden durch ein MediaRouteSelector festgelegt. Aktivität seit AppCompatActivity verlängern und erstellen Sie den Selektor, wenn die Aktivität erstellt wird und MediaRouteSelector.Builder aufgerufen wird. aus der onCreate()-Methode, wie hier gezeigt, im folgenden Codebeispiel. Die Auswahl wird in einer Klassenvariablen gespeichert und die zulässigen Routentypen sind angegeben. indem Sie MediaControlIntent-Objekte hinzufügen:

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();
    }
}

Für die meisten Anwendungen Der erforderliche Routentyp ist CATEGORY_REMOTE_PLAYBACK. Bei diesem Routentyp wird das Gerät, auf dem deine App ausgeführt wird, als Fernbedienung behandelt. Der gesamte Abruf, die Decodierung und die Wiedergabe von Inhaltsdaten übernimmt das angeschlossene Empfängergerät. So sehen Apps, die Google Cast unterstützen, wie Chromecast, zur Arbeit!

Einige Hersteller unterstützen eine spezielle Routingoption namens "Sekundärausgabe". Bei diesem Routing werden Ihre Die Medien-App ruft Videos oder Musik ab, rendert sie und streamt sie direkt auf den Bildschirm und/oder Lautsprecher des ausgewählten Remote-Receivers. Verwenden Sie den sekundären Ausgang, um Inhalte an kabellose Musiksysteme oder Bildschirme zu senden. Um die Erkennung und diese Geräte ausgewählt haben, müssen Sie den CATEGORY_LIVE_AUDIO oder CATEGORY_LIVE_VIDEO Kategorien an den MediaRouteSelector. Außerdem müssen Sie ein eigenes Presentation-Dialogfeld erstellen und verwalten.

Schaltfläche für Medienroute zur Aktionsleiste hinzufügen

Nachdem Sie das Menü für die Medienroute und den MediaRouteSelector definiert haben, können Sie jetzt die Schaltfläche für die Medienroute zu einer Aktivität hinzufügen. Überschreiben Sie die Methode onCreateOptionsMenu() für jede Ihrer Aktivitäten, um eine Option hinzuzufügen .

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;
}

Weitere Informationen zum Implementieren der Aktionsleiste in Ihrer App sehen Sie sich die Aktionsleiste an. Entwicklerleitfaden.

Du kannst eine Medienroute-Schaltfläche auch als MediaRouteButton in jedem Ansicht. Du musst mithilfe der Methode setRouteSelector() einen MediaRouteSelector an die Schaltfläche anhängen. Weitere Informationen finden Sie in der Checkliste für das Design von Google Cast finden Sie Richtlinien zum Integrieren der Medienroute-Schaltfläche in Ihre Anwendung.

MediaRouter-Rückrufe

Alle Apps, die auf demselben Gerät ausgeführt werden, verwenden eine einzige MediaRouter-Instanz und ihre Routen. (gefiltert nach App durch den MediaRouteSelector der App). Jede Aktivität kommuniziert mit dem MediaRouter. mit eigener MediaRouter.Callback-Implementierung . Der MediaRouter ruft die Callback-Methoden auf, wenn der Nutzer eine Route auswählt, ändert oder trennt.

Es gibt mehrere Methoden im Callback, die Sie überschreiben können, um Informationen zu Routing-Ereignisse. Ihre Implementierung der MediaRouter.Callback-Klasse sollte mindestens onRouteSelected() und onRouteUnselected()

Da der MediaRouter eine gemeinsam genutzte Ressource ist, muss Ihre App seine MediaRouter-Callbacks verwalten. als Reaktion auf die üblichen Callbacks für den Aktivitätslebenszyklus:

  • Wenn die Aktivität erstellt wurde (onCreate(Bundle)), greifen Sie auf die MediaRouter und behalten Sie sie für die Lebensdauer der App bei.
  • Hängen Sie Callbacks an MediaRouter an, wenn die Aktivität sichtbar wird (onStart()), und trennen Sie sie, wenn sie ausgeblendet ist (onStop())

Im folgenden Codebeispiel wird veranschaulicht, wie Sie das Callback-Objekt erstellen und speichern, eine MediaRouter-Instanz abrufen und Callbacks verwalten Beachten Sie die Verwendung des Flags CALLBACK_FLAG_REQUEST_DISCOVERY beim Anhängen der Callbacks in onStart(). So kann der MediaRouteSelector Liste der verfügbaren Routen.

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();
    }
    ...
}

Das Media Router-Framework bietet außerdem MediaRouteDiscoveryFragment, die das Hinzufügen und Hinzufügen Entfernen des Callbacks für eine Aktivität

Hinweis:Wenn Sie eine App zur Musikwiedergabe entwickeln und möchten, dass die App Musik im Hintergrund abspielen, musst du für die Wiedergabe eine Service erstellen. und rufen Sie das Media Router-Framework aus den Lebenszyklus-Callbacks des Dienstes auf.

Route für die Remote-Wiedergabe steuern

Wenn du eine Route für die Remote-Wiedergabe auswählst, fungiert deine App als Fernbedienung. Das Gerät am anderen Ende der Route übernimmt alle Funktionen für den Abruf, die Decodierung und die Wiedergabe von Inhaltsdaten. Die Steuerelemente in der Benutzeroberfläche Ihrer App kommunizieren über ein RemotePlaybackClient-Objekt.

Die Klasse RemotePlaybackClient bietet zusätzliche Methoden zur Verwaltung der Wiedergabe von Inhalten. Hier sind einige der wichtigsten Wiedergabemethoden der RemotePlaybackClient-Klasse:

  • play() – Spielt ein bestimmtes Mediendatei, die durch Uri angegeben wird.
  • pause(): Pausieren Sie die Medien-Track wird gerade wiedergegeben.
  • resume() – Weiter den aktuellen Track nach einem Pause-Befehl wiedergeben.
  • seek(): zu einem bestimmten Position im aktuellen Track.
  • release() – Reiße das Verbindung zwischen deiner App und dem Remote-Wiedergabegerät.

Mit diesen Methoden können Sie Aktionen an die Wiedergabesteuerung anhängen, die Sie in Ihrem Bei den meisten dieser Methoden können Sie auch ein Callback-Objekt einfügen, den Fortschritt der Wiedergabeaufgabe oder Steuerungsanfrage.

Die Klasse RemotePlaybackClient unterstützt auch die Wiedergabeliste Mehrere Medienelemente zur Wiedergabe und Verwaltung der Medienwarteschlange

Beispielcode

Den Android BasicMediaRouter und MediaRouter veranschaulichen die Verwendung der MediaRouter-API.