Thêm các tính năng nâng cao vào ứng dụng Android

Điểm chèn quảng cáo

Android Sender SDK hỗ trợ tính năng Điểm chèn quảng cáo và quảng cáo đồng hành trong một luồng nội dung nghe nhìn nhất định.

Hãy xem phần Tổng quan về điểm chèn quảng cáo trên trình nhận trên web để biết thêm thông tin về cách hoạt động của điểm chèn quảng cáo.

Mặc dù có thể chỉ định thời điểm ngắt quảng cáo trên cả người gửi và người nhận, nhưng bạn nên chỉ định các điểm chèn quảng cáo này trên Trình thu thập dữ liệu trên webBộ thu của Android TV để duy trì hành vi nhất quán trên các nền tảng.

Trên Android, hãy chỉ định điểm chèn quảng cáo trong một lệnh tải bằng cách sử dụng 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);

Thêm thao tác tuỳ chỉnh

Ứng dụng của người gửi có thể mở rộng MediaIntentReceiver để xử lý các thao tác tuỳ chỉnh hoặc ghi đè hành vi của ứng dụng đó. Nếu đã triển khai MediaIntentReceiver của riêng mình, bạn cần thêm tệp đó vào tệp kê khai và đặt tên cho tệp đó trong CastMediaOptions. Ví dụ này cung cấp các thao tác tuỳ chỉnh ghi đè nút bật/tắt chế độ phát nội dung nghe nhìn từ xa, nhấn nút đa phương tiện và các loại thao tác khác.

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

Thêm kênh tuỳ chỉnh

Để ứng dụng của người gửi giao tiếp với ứng dụng nhận, ứng dụng của bạn cần tạo một kênh tuỳ chỉnh. Người gửi có thể sử dụng kênh tuỳ chỉnh để gửi thông điệp chuỗi cho người nhận. Mỗi kênh tuỳ chỉnh được xác định bằng một không gian tên duy nhất và phải bắt đầu bằng tiền tố urn:x-cast:, chẳng hạn như urn:x-cast:com.example.custom. Bạn có thể có nhiều kênh tuỳ chỉnh, mỗi kênh có một không gian tên riêng. Ứng dụng receiver cũng có thể gửi và nhận thông báo bằng cùng một không gian tên.

Kênh tuỳ chỉnh được triển khai bằng giao diện 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);
    }
}

Sau khi ứng dụng của người gửi được kết nối với ứng dụng nhận, bạn có thể tạo kênh tuỳ chỉnh bằng phương thức 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);
}

Sau khi tạo kênh tuỳ chỉnh, người gửi có thể sử dụng phương thức sendMessage để gửi thông báo chuỗi đến người nhận qua kênh đó:

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

Hỗ trợ tính năng tự động phát

Xem phần API Tự động phát và Xếp hàng.

Ghi đè lựa chọn hình ảnh cho các tiện ích trải nghiệm người dùng

Nhiều thành phần của khung (cụ thể là hộp thoại Truyền, bộ điều khiển thu nhỏ và UIMediaController, nếu được định cấu hình) sẽ hiển thị hình minh hoạ cho nội dung nghe nhìn hiện đang truyền. URL đến hình minh hoạ thường được đưa vào MediaMetadata cho nội dung nghe nhìn, nhưng ứng dụng gửi có thể có nguồn thay thế cho các URL.

Lớp ImagePicker xác định phương tiện để chọn hình ảnh thích hợp từ danh sách hình ảnh trong MediaMetadata, dựa trên việc sử dụng hình ảnh, chẳng hạn như hình thu nhỏ thông báo hoặc nền toàn màn hình. Phương thức triển khai ImagePicker mặc định luôn chọn hình ảnh đầu tiên hoặc trả về giá trị rỗng nếu không có hình ảnh nào trong MediaMetadata. Ứng dụng của bạn có thể phân lớp con ImagePicker và ghi đè phương thức onPickImage(MediaMetadata, ImageHints) để cung cấp phương thức triển khai thay thế, sau đó chọn lớp con đó bằng phương thức setImagePicker của CastMediaOptions.Builder. ImageHints đưa ra gợi ý cho ImagePicker về loại và kích thước hình ảnh sẽ được chọn để hiển thị trong giao diện người dùng.

Tuỳ chỉnh hộp thoại Truyền

Quản lý Vòng đời phiên

SessionManager là trung tâm để quản lý vòng đời của phiên hoạt động. SessionManager theo dõi các thay đổi về trạng thái lựa chọn định tuyến MediaRouter của Android để bắt đầu, tiếp tục và kết thúc phiên. Khi bạn chọn một tuyến, SessionManager sẽ tạo đối tượng Session và cố gắng bắt đầu hoặc tiếp tục tuyến đó. Khi không chọn một tuyến, SessionManager sẽ kết thúc phiên hiện tại.

Do đó, để đảm bảo SessionManager quản lý vòng đời của phiên đúng cách, bạn phải đảm bảo rằng:

Tuỳ thuộc vào cách tạo hộp thoại Truyền, bạn có thể cần thực hiện các thao tác khác:

Trạng thái không có thiết bị

Nếu bạn tạo hộp thoại Truyền tuỳ chỉnh, thì MediaRouteChooserDialog tuỳ chỉnh của bạn sẽ xử lý đúng cách trong trường hợp không tìm thấy thiết bị nào. Hộp thoại phải có các chỉ báo cho người dùng biết rõ khi nào ứng dụng vẫn đang cố tìm thiết bị và khi nào hoạt động khám phá không còn hoạt động nữa.

Nếu bạn đang sử dụng MediaRouteChooserDialog mặc định, thì trạng thái 0 thiết bị đã được xử lý.

Các bước tiếp theo

Bài này kết thúc các tính năng mà bạn có thể thêm vào ứng dụng Android Sender (Người gửi email) của mình. Giờ đây, bạn có thể tạo ứng dụng dành cho người gửi cho một nền tảng khác (iOS hoặc Web) hoặc tạo ứng dụng Trình thu thập dữ liệu trên web.