Điểm chèn quảng cáo
Android Sender SDK hỗ trợ các Đ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 của Web Receiver để 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ù bạn có thể chỉ định điểm chèn quảng cáo trên cả thiết bị gửi và thiết bị nhận, nhưng bạn nên chỉ định điểm chèn quảng cáo trên Web Receiver và Android TV Receiver để 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 lệnh tải bằng cách sử dụng AdBreakClipInfo
và 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);
Thêm thao tác tuỳ chỉnh
Ứng dụng 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 thao tác đó. Nếu đã triển khai MediaIntentReceiver
của riêng mình, bạn cần thêm MediaIntentReceiver
đó vào tệp kê khai, đồng thời đặt tên của MediaIntentReceiver
đó trong CastMediaOptions
. Ví dụ này cung cấp các thao tác tuỳ chỉnh để ghi đè chế độ bật/tắt tính năng 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" />
// 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) { } }
Thêm kênh tuỳ chỉnh
Để ứng dụng 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 báo dạng 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 riêng biệt và phải bắt đầu bằng tiền tố urn:x-cast:
, ví dụ: 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 biệt. Ứng dụng nhận cũng có thể gửi và nhận thông báo bằng cách sử dụ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
:
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); } }
Sau khi ứng dụng 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
:
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); }
Sau khi tạo kênh tuỳ chỉnh, người gửi có thể dùng phương thức sendMessage
để gửi thông báo dạng chuỗi cho người nhận qua kênh đó:
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); } } }
Hỗ trợ tính năng tự động phát
Xem phần API Tự động phát và API Xếp hàng.
Ghi đè lựa chọn hình ảnh cho các tiện ích UX
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ị ảnh minh hoạ cho nội dung nghe nhìn đang được truyền. URL của ảnh minh hoạ thường có trong MediaMetadata
của nội dung nghe nhìn, nhưng ứng dụng người gửi có thể có một nguồn thay thế cho các URL này.
Lớp ImagePicker
xác định một phương tiện để chọn hình ảnh phù hợp trong danh sách hình ảnh trong MediaMetadata
, dựa trên mục đích sử dụng hình ảnh, ví dụ: hình thu nhỏ thông báo hoặc nền toàn màn hình. Hoạt động 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ể tạo lớp con ImagePicker
và ghi đè phương thức onPickImage(MediaMetadata, ImageHints)
để cung cấp một cách triển khai thay thế, sau đó chọn lớp con đó bằng phương thức setImagePicker
của CastMediaOptions.Builder
.
ImageHints
cung cấp gợi ý cho ImagePicker
về loại và kích thước của 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 của phiên
SessionManager
là nơi tập trung để quản lý vòng đời của phiên. SessionManager
lắng nghe các thay đổi về trạng thái lựa chọn tuyến đường MediaRouter
của Android để bắt đầu, tiếp tục và kết thúc các phiên. Khi một tuyến đường được chọn, SessionManager
sẽ tạo một đối tượng Session
và cố gắng bắt đầu hoặc tiếp tục đối tượng đó. Khi một tuyến đường bị bỏ chọn, SessionManager
sẽ kết thúc phiên hiện tại.
Do đó, để đảm bảo SessionManager
quản lý đúng vòng đời của phiên, bạn phải đảm bảo rằng:
- Trong hộp thoại bộ chọn tuyến đường, hãy gọi
MediaRouter.selectRoute(MediaRouter.RouteInfo)
khi người dùng chọn một thiết bị. - Trong hộp thoại bộ điều khiển tuyến đường (ở trạng thái đã kết nối hoặc trạng thái truyền), hãy gọi
MediaRouter.unselect(int)
khi người dùng dừng truyền.
Tuỳ thuộc vào cách bạn tạo hộp thoại Truyền, bạn có thể cần thực hiện thêm các thao tác sau:
- Nếu bạn tạo hộp thoại Truyền bằng
MediaRouteChooserDialog
vàMediaRouteControllerDialog
, thì các hộp thoại này sẽ tự động cập nhật lựa chọn tuyến đường trongMediaRouter
, nên bạn không cần làm gì cả. - Nếu bạn thiết lập nút Truyền bằng
CastButtonFactory.setUpMediaRouteButton(Context, Menu, int)
hoặcCastButtonFactory.setUpMediaRouteButton(Context, MediaRouteButton)
, thì các hộp thoại thực sự được tạo bằngMediaRouteChooserDialog
vàMediaRouteControllerDialog
, nên bạn cũng không cần làm gì cả. - Đối với các trường hợp khác, bạn sẽ tạo hộp thoại Truyền tuỳ chỉnh, vì vậy, bạn cần làm theo hướng dẫn ở trên để cập nhật trạng thái chọn tuyến đường trong
MediaRouter
.
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 phải xử lý đúng 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 giúp người dùng biết rõ khi ứng dụng của bạn vẫn đang cố gắng tìm thiết bị và khi quá trình tìm kiếm 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 không có thiết bị đã được xử lý.
Các bước tiếp theo
Đến đây là kết thúc các tính năng mà bạn có thể thêm vào ứng dụng Người gửi Android. Giờ đây, bạn có thể tạo một ứng dụng người gửi cho một nền tảng khác (iOS hoặc Web) hoặc tạo một ứng dụng Web Receiver.