Ihrer Android-App erweiterte Funktionen hinzufügen

Werbeunterbrechungen

Das Android Sender SDK unterstützt Werbeunterbrechungen und Companion-Anzeigen in einem bestimmten Media-Stream.

Weitere Informationen zu Werbeunterbrechungen finden Sie in der Übersicht zu Werbeunterbrechungen im Web Receiver für weitere Informationen dazu, wie Werbeunterbrechungen funktionieren.

Unterbrechungen können sowohl auf dem Sender als auch auf dem Receiver angegeben werden. Es wird jedoch empfohlen, sie auf dem Web Receiver und dem Android TV Receiver anzugeben, um ein einheitliches Verhalten auf allen Plattformen zu gewährleisten.

Geben Sie auf Android Werbeunterbrechungen in einem Ladebefehl mit AdBreakClipInfo und AdBreakInfo an:

Kotlin
val breakClip1: AdBreakClipInfo =
    AdBreakClipInfo.Builder("bc0")
        .setTitle("Clip title")
        .setPosterUrl("https://www.some.url")
        .setDuration(60000)
        .setWhenSkippableInMs(5000)  // Set this field so that the ad is skippable
        .build()

val breakClip2: AdBreakClipInfo = 
val breakClip3: AdBreakClipInfo = 

val break1: AdBreakClipInfo =
    AdBreakInfo.Builder(/* playbackPositionInMs= */ 10000)
        .setId("b0")
        .setBreakClipIds({"bc0","bc1","bc2"})
        
        .build()

val mediaInfo: MediaInfo = MediaInfo.Builder()
    
    .setAdBreaks({break1})
    .setAdBreakClips({breakClip1, breakClip2, breakClip3})
    .build()

val mediaLoadRequestData: MediaLoadRequestData = MediaInfo.Builder()
    
    .setMediaInfo(mediaInfo)
    .build()

remoteMediaClient.load(mediaLoadRequestData)
Java
AdBreakClipInfo breakClip1 =
    new AdBreakClipInfo.Builder("bc0")
        .setTitle("Clip title")
        .setPosterUrl("https://www.some.url")
        .setDuration(60000)
        .setWhenSkippableInMs(5000)  // Set this field so that the ad is skippable
        .build();

AdBreakClipInfo breakClip2 = 
AdBreakClipInfo breakClip3 = 

AdBreakInfo break1 =
    new AdBreakInfo.Builder(/* playbackPositionInMs= */ 10000)
        .setId("b0")
        .setBreakClipIds({"bc0","bc1","bc2"})
        
        .build();

MediaInfo mediaInfo = new MediaInfo.Builder()
    
    .setAdBreaks({break1})
    .setAdBreakClips({breakClip1, breakClip2, breakClip3})
    .build();

MediaLoadRequestData mediaLoadRequestData = new MediaInfo.Builder()
    
    .setMediaInfo(mediaInfo)
    .build();

remoteMediaClient.load(mediaLoadRequestData);

Benutzerdefinierte Aktionen hinzufügen

Eine Sender-App kann MediaIntentReceiver erweitern, um benutzerdefinierte Aktionen zu verarbeiten oder das Verhalten zu überschreiben. Wenn Sie einen eigenen MediaIntentReceiver implementiert haben, müssen Sie ihn dem Manifest hinzufügen und seinen Namen auch in den CastMediaOptions festlegen. Dieses Beispiel enthält benutzerdefinierte Aktionen, mit denen die Wiedergabe von Medieninhalten auf einem Remote-Gerät ein- und ausgeschaltet, die Medientaste gedrückt und andere Aktionen ausgeführt werden können.

// In AndroidManifest.xml
<receiver android:name="com.example.MyMediaIntentReceiver" />
Kotlin
// In your OptionsProvider
var mediaOptions = CastMediaOptions.Builder()
    .setMediaIntentReceiverClassName(MyMediaIntentReceiver::class.java.name)
    .build()

// Implementation of MyMediaIntentReceiver
internal class MyMediaIntentReceiver : MediaIntentReceiver() {
    override fun onReceiveActionTogglePlayback(currentSession: Session) {
    }

    override fun onReceiveActionMediaButton(currentSession: Session, intent: Intent) {
    }

    override fun onReceiveOtherAction(context: Context?, action: String, intent: Intent) {
    }
}
Java
// In your OptionsProvider
CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
        .setMediaIntentReceiverClassName(MyMediaIntentReceiver.class.getName())
        .build();

// Implementation of MyMediaIntentReceiver
class MyMediaIntentReceiver extends MediaIntentReceiver {
    @Override
    protected void onReceiveActionTogglePlayback(Session currentSession) {
    }

    @Override
    protected void onReceiveActionMediaButton(Session currentSession, Intent intent) {
    }

    @Override
    protected void onReceiveOtherAction(Context context, String action, Intent intent) {
    }
}

Benutzerdefinierten Kanal hinzufügen

Damit die Sender-App mit der Receiver-App kommunizieren kann, muss Ihre App einen benutzerdefinierten Kanal erstellen. Der Sender kann über den benutzerdefinierten Kanal String-Nachrichten an den Receiver senden. Jeder benutzerdefinierte Kanal wird durch einen eindeutigen Namespace definiert und muss mit dem Präfix urn:x-cast: beginnen, z. B. urn:x-cast:com.example.custom. Es können mehrere benutzerdefinierte Kanäle mit jeweils einem eindeutigen Namespace vorhanden sein. Die Receiver-App kann auch Nachrichten senden und empfangen mit demselben Namespace.

Der benutzerdefinierte Kanal wird mit der Cast.MessageReceivedCallback Schnittstelle implementiert:

Kotlin
class HelloWorldChannel : MessageReceivedCallback {
    val namespace: String
        get() = "urn:x-cast:com.example.custom"

    override fun onMessageReceived(castDevice: CastDevice, namespace: String, message: String) {
        Log.d(TAG, "onMessageReceived: $message")
    }
}
Java
class HelloWorldChannel implements Cast.MessageReceivedCallback {
    public String getNamespace() {
        return "urn:x-cast:com.example.custom";
    }
    @Override
    public void onMessageReceived(CastDevice castDevice, String namespace, String message) {
        Log.d(TAG, "onMessageReceived: " + message);
    }
}

Sobald die Sender-App mit der Receiver-App verbunden ist, kann der benutzerdefinierte Kanal mit der Methode setMessageReceivedCallbacks erstellt werden:

Kotlin
try {
    mCastSession.setMessageReceivedCallbacks(
        mHelloWorldChannel.namespace,
        mHelloWorldChannel)
} catch (e: IOException) {
    Log.e(TAG, "Exception while creating channel", e)
}
Java
try {
    mCastSession.setMessageReceivedCallbacks(
            mHelloWorldChannel.getNamespace(),
            mHelloWorldChannel);
} catch (IOException e) {
    Log.e(TAG, "Exception while creating channel", e);
}

Nachdem der benutzerdefinierte Kanal erstellt wurde, kann der Sender mit der sendMessage Methode String-Nachrichten über diesen Kanal an den Receiver senden:

Kotlin
private fun sendMessage(message: String) {
    if (mHelloWorldChannel != null) {
        try {
            mCastSession.sendMessage(mHelloWorldChannel.namespace, message)
                .setResultCallback { status ->
                    if (!status.isSuccess) {
                        Log.e(TAG, "Sending message failed")
                    }
                }
        } catch (e: Exception) {
            Log.e(TAG, "Exception while sending message", e)
        }
    }
}
Java
private void sendMessage(String message) {
    if (mHelloWorldChannel != null) {
        try {
            mCastSession.sendMessage(mHelloWorldChannel.getNamespace(), message)
                .setResultCallback( status -> {
                    if (!status.isSuccess()) {
                        Log.e(TAG, "Sending message failed");
                    }
                });
        } catch (Exception e) {
            Log.e(TAG, "Exception while sending message", e);
        }
    }
}

Autoplay unterstützen

Weitere Informationen finden Sie im Abschnitt Autoplay- und Warteschlangen-APIs.

Bildauswahl für UX-Widgets überschreiben

In verschiedenen Komponenten des Frameworks (nämlich im Cast-Dialogfeld, im Mini-Controller und im UIMediaController, falls konfiguriert) werden Grafiken für die aktuell übertragenen Medieninhalte angezeigt. Die URLs zu den Grafiken sind in der Regel in den MediaMetadata für die Medieninhalte enthalten. Die Sender-App kann jedoch eine alternative Quelle für die URLs haben.

Die ImagePicker Klasse definiert eine Möglichkeit, ein geeignetes Bild aus der Liste der Bilder in einem MediaMetadataauszuwählen, basierend auf der Verwendung des Bildes, z. B. als Miniaturansicht für Benachrichtigungen oder als Vollbildhintergrund. Die Standardimplementierung von ImagePicker wählt immer das erste Bild aus oder gibt „null“ zurück, wenn in den MediaMetadata kein Bild verfügbar ist. Ihre App kann ImagePicker unterklassen und die onPickImage(MediaMetadata, ImageHints) Methode überschreiben, um eine alternative Implementierung bereitzustellen. Wählen Sie dann diese Unterklasse mit der setImagePicker Methode von CastMediaOptions.Builder aus. ImageHints enthält Hinweise für ImagePicker zum Typ und zur Größe eines Bildes, das für die Anzeige in der Benutzeroberfläche ausgewählt werden soll.

Cast-Dialogfelder anpassen

Sitzungslebenszyklus verwalten

SessionManager ist der zentrale Ort für die Verwaltung des Sitzungslebenszyklus. SessionManager überwacht Änderungen des Auswahlstatus der Android MediaRouter -Route, um Sitzungen zu starten, fortzusetzen und zu beenden. Wenn eine Route ausgewählt wird, erstellt SessionManager ein Session Objekt und versucht, es zu starten oder fortzusetzen. Wenn die Auswahl einer Route aufgehoben wird, beendet SessionManager die aktuelle Sitzung.

Damit SessionManager Sitzungslebenszyklen ordnungsgemäß verwalten kann, müssen Sie Folgendes beachten:

Je nachdem, wie Sie die Cast-Dialogfelder erstellen, sind möglicherweise zusätzliche Aktionen erforderlich:

Status „Keine Geräte“

Wenn Sie benutzerdefinierte Cast-Dialogfelder erstellen, sollte Ihr benutzerdefiniertes MediaRouteChooserDialog den Fall verarbeiten, dass keine Geräte gefunden werden. Das Dialogfeld sollte Indikatoren enthalten, die Nutzern zeigen, wann Ihre App noch versucht, Geräte zu finden, und wann der Suchvorgang nicht mehr aktiv ist.

Wenn Sie das Standard-MediaRouteChooserDialog verwenden, wird der Status „Keine Geräte“ bereits verarbeitet.

Nächste Schritte

Damit sind alle Funktionen abgedeckt, die Sie Ihrer Android Sender-App hinzufügen können. Sie können jetzt eine Sender-App für eine andere Plattform erstellen (iOS oder Web) oder eine Web Receiver-App erstellen.