Przerwy na reklamę
Pakiet Android Sender SDK obsługuje przerwy na reklamy i reklamy towarzyszące w ramach danego strumienia multimediów.
Więcej informacji o działaniu przerw na reklamy znajdziesz w artykule Przerwy na reklamy w odbiorniku internetowym – omówienie.
Przerwy można określać zarówno na nadajniku, jak i odbiorniku, ale zalecamy określanie ich na odbiorniku internetowym i odbiorniku Androida TV, aby zachować spójne działanie na różnych platformach.
Na Androidzie określ przerwy na reklamę w poleceniu wczytywania za pomocą tych parametrów:AdBreakClipInfo
AdBreakInfo
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)
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);
Dodawanie działań niestandardowych
Aplikacja wysyłająca może rozszerzać MediaIntentReceiver
, aby obsługiwać działania niestandardowe lub zastępować jej działanie. Jeśli masz własną MediaIntentReceiver
, musisz dodać ją do pliku manifestu i ustawić jej nazwę w CastMediaOptions
. Ten przykład zawiera niestandardowe działania, które zastępują przełączanie zdalnego odtwarzania multimediów, naciśnięcie przycisku multimediów i inne rodzaje działań.
// In AndroidManifest.xml
<receiver android:name="com.example.MyMediaIntentReceiver" />
// 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) { } }
// 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) { } }
Dodawanie kanału niestandardowego
Aby aplikacja wysyłająca mogła komunikować się z aplikacją odbierającą, musi utworzyć kanał niestandardowy. Nadawca może używać niestandardowego kanału do wysyłania wiadomości tekstowych do odbiorcy. Każdy kanał niestandardowy jest określany przez unikalną przestrzeń nazw i musi zaczynać się od prefiksu urn:x-cast:
, np. urn:x-cast:com.example.custom
. Możesz mieć wiele kanałów niestandardowych, z których każdy ma unikalną przestrzeń nazw. Aplikacja odbiorcy może też wysyłać i odbierać wiadomości w tej samej przestrzeni nazw.
Kanał niestandardowy jest implementowany za pomocą interfejsu
Cast.MessageReceivedCallback
:
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") } }
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); } }
Gdy aplikacja wysyłająca jest połączona z aplikacją odbierającą, można utworzyć kanał niestandardowy za pomocą metody setMessageReceivedCallbacks
:
try { mCastSession.setMessageReceivedCallbacks( mHelloWorldChannel.namespace, mHelloWorldChannel) } catch (e: IOException) { Log.e(TAG, "Exception while creating channel", e) }
try { mCastSession.setMessageReceivedCallbacks( mHelloWorldChannel.getNamespace(), mHelloWorldChannel); } catch (IOException e) { Log.e(TAG, "Exception while creating channel", e); }
Po utworzeniu kanału niestandardowego nadawca może użyć metody
sendMessage
do wysyłania wiadomości tekstowych do odbiorcy za pośrednictwem tego kanału:
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) } } }
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); } } }
Obsługa autoodtwarzania
Zapoznaj się z sekcją Interfejsy Autoodtwarzanie i kolejkowanie.
Zastępowanie wyboru obrazu w przypadku widżetów UX
Różne komponenty platformy (mianowicie okno przesyłania, minikontroler i UIMediaController, jeśli jest skonfigurowany) będą wyświetlać grafikę aktualnie przesyłanych multimediów. Adresy URL grafiki są zwykle zawarte w elemencie MediaMetadata
dla multimediów, ale aplikacja wysyłająca może mieć alternatywne źródło adresów URL.
Klasa
ImagePicker
określa sposób wybierania odpowiedniego obrazu z listy obrazów
w MediaMetadata
na podstawie zastosowania obrazu, np. miniatury powiadomienia
lub tła na pełnym ekranie. Domyślna implementacja ImagePicker
zawsze wybiera pierwszy obraz lub zwraca wartość null, jeśli w MediaMetadata
nie ma żadnego obrazu. Aplikacja może utworzyć podklasę ImagePicker
i zastąpić metodę
onPickImage(MediaMetadata, ImageHints)
w celu udostępnienia alternatywnej implementacji, a następnie wybrać tę podklasę za pomocą metody
setImagePicker
klasy CastMediaOptions.Builder
.
ImageHints
zawiera wskazówki dla ImagePicker
dotyczące typu i rozmiaru obrazu, który ma być
wybrany do wyświetlenia w interfejsie.
Dostosowywanie okien przesyłania
Zarządzanie cyklem życia sesji
SessionManager
to centralne miejsce zarządzania cyklem życia sesji. SessionManager
nasłuchuje
zmian stanu wyboru trasy w Androidzie
MediaRouter
w celu rozpoczynania, wznawiania i kończenia sesji. Gdy wybierzesz trasę, SessionManager
utworzy obiekt Session
i spróbuje go uruchomić lub wznowić. Gdy trasa zostanie odznaczona,SessionManager
zakończy bieżącą sesję.
Aby mieć pewność, że SessionManager
prawidłowo zarządza cyklami życia sesji, musisz zadbać o to, aby:
- W oknie wyboru trasy wywołaj
MediaRouter.selectRoute(MediaRouter.RouteInfo)
, gdy użytkownik wybierze urządzenie. - W oknie kontrolera trasy (w stanie połączenia lub przesyłania) wywołaj
MediaRouter.unselect(int)
, gdy użytkownik przestanie przesyłać.
W zależności od sposobu tworzenia okien przesyłania może być konieczne wykonanie dodatkowych działań:
- Jeśli tworzysz okna Cast za pomocą
MediaRouteChooserDialog
iMediaRouteControllerDialog
, wybór trasy wMediaRouter
będzie aktualizowany automatycznie, więc nie musisz nic robić. - Jeśli przycisk Cast został skonfigurowany za pomocą
CastButtonFactory.setUpMediaRouteButton(Context, Menu, int)
lubCastButtonFactory.setUpMediaRouteButton(Context, MediaRouteButton)
, dialogi są tworzone za pomocąMediaRouteChooserDialog
iMediaRouteControllerDialog
, więc nie musisz nic robić. - W innych przypadkach będziesz tworzyć niestandardowe okna dialogowe przesyłania, więc musisz postępować zgodnie z powyższymi instrukcjami, aby zaktualizować stan wyboru trasy w
MediaRouter
.
Stan braku urządzeń
Jeśli tworzysz niestandardowe okna przesyłania, Twój niestandardowy element MediaRouteChooserDialog
powinien prawidłowo obsługiwać sytuację, w której nie znaleziono żadnych urządzeń. W oknie dialogowym powinny być widoczne wskaźniki informujące użytkowników, kiedy aplikacja nadal próbuje znaleźć urządzenia, a kiedy próba wykrycia nie jest już aktywna.
Jeśli używasz domyślnego MediaRouteChooserDialog
, stan braku urządzeń jest już obsługiwany.
Dalsze kroki
To już wszystkie funkcje, które możesz dodać do aplikacji nadawcy na Androida. Teraz możesz utworzyć aplikację nadawcy na inną platformę (iOS lub sieć) albo utworzyć aplikację odbiorcy internetowego.