為您的 Android 應用程式新增進階功能

廣告插播

Android send SDK 支援特定媒體串流中的廣告插播和隨播廣告。

如要進一步瞭解廣告插播的運作方式,請參閱網路廣告插播總覽

雖然可以同時為傳送者和接收者指定中斷點,但我們建議您透過網路接收器Android TV 接收器指定中斷點,以保持跨平台維持一致的行為。

在 Android 上,請使用 AdBreakClipInfoAdBreakInfo 在載入指令中指定廣告插播時間點:

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

新增自訂動作

寄件者應用程式可以擴充 MediaIntentReceiver 以處理自訂動作或覆寫其行為。如果實作了自己的 MediaIntentReceiver,則必須將其新增至資訊清單,並在 CastMediaOptions 中設定名稱。這個範例提供自訂動作,可覆寫遠端媒體播放、按下媒體按鈕和其他類型的動作。

// 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) {
    }
}

新增自訂管道

為了讓傳送者與接收端應用程式相互通訊,您的應用程式必須建立自訂頻道。傳送者可使用自訂管道,將字串訊息傳送至接收器。每個自訂管道都是由不重複的命名空間定義,且開頭必須是 urn:x-cast: 前置字串。例如 urn:x-cast:com.example.custom。您可能會有多個自訂管道,且每個頻道都有不重複的命名空間。接收器應用程式也可以使用相同命名空間收發訊息

使用 Cast.MessageReceivedCallback 介面實作自訂管道:

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

傳送方應用程式連線至接收器應用程式後,即可使用 setMessageReceivedCallbacks 方法建立自訂頻道:

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

建立自訂管道後,傳送者可使用 sendMessage 方法,透過該管道將字串訊息傳送至接收器:

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

支援自動播放功能

請參閱「自動播放和佇列 API」一節。

覆寫使用者體驗小工具的圖片選取功能

架構的各種元件 (也就是「投放」對話方塊、迷你控制器和 UIMediaController) (如果有設定的話),會顯示目前投放媒體的藝術品。圖片圖片的網址通常包含在媒體的 MediaMetadata 中,但寄件者應用程式可能會為網址提供替代來源。

ImagePicker 類別定義根據圖片的使用方式,從 MediaMetadata 中的圖片清單中選取適當的圖片,例如通知縮圖或全螢幕背景。預設的 ImagePicker 實作會選擇第一張圖片,如果 MediaMetadata 中沒有任何圖片,則會傳回空值。您的應用程式可以為 ImagePicker 建立子類別,並覆寫 onPickImage(MediaMetadata, ImageHints) 方法以提供替代實作方式,然後使用 CastMediaOptions.BuildersetImagePicker 方法選取該子類別。ImageHints 針對 ImagePicker 中選擇要顯示在使用者介面中的圖片類型和大小提供提示。

自訂投放對話方塊

SessionManager 是管理工作階段生命週期的核心。SessionManager 會監聽 Android MediaRouter 路徑選取狀態變更,以便開始、繼續及結束工作階段。選取路徑後,SessionManager 會建立 Session 物件,並嘗試開始或重新啟用。如未選取路徑,SessionManager 會結束目前的工作階段。

因此,為了確保 SessionManager 能正確管理工作階段生命週期,您必須確認:

視建立「投放」對話方塊的方式而定,您可能需要完成其他動作:

後續步驟

可以判斷可新增至 Android 傳送端應用程式的功能。您現在可以為其他平台 (iOS網頁) 建構傳送端應用程式,或是建構網路接收器應用程式