ویژگی های پیشرفته را به برنامه اندروید خود اضافه کنید

خرابی های تبلیغاتی

Android Sender SDK از Ad Breaks و تبلیغات همراه در یک جریان رسانه ای خاص پشتیبانی می کند.

برای کسب اطلاعات بیشتر در مورد نحوه عملکرد وقفه‌های تبلیغاتی، به نمای کلی وقفه‌های تبلیغاتی گیرنده وب مراجعه کنید.

در حالی که می‌توان وقفه‌ها را هم بر روی فرستنده و هم بر روی گیرنده مشخص کرد، توصیه می‌شود که آنها را در گیرنده وب و گیرنده Android TV مشخص کنید تا رفتار ثابت در بین پلتفرم‌ها حفظ شود.

در Android، با استفاده از 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);

افزودن اقدامات سفارشی

یک برنامه فرستنده می تواند MediaIntentReceiver گسترش دهد تا اقدامات سفارشی را انجام دهد یا رفتار آن را نادیده بگیرد. اگر MediaIntentReceiver خود را پیاده‌سازی کرده‌اید، باید آن را به مانیفست اضافه کنید و همچنین نام آن را در CastMediaOptions تنظیم کنید. این مثال کنش‌های سفارشی را ارائه می‌کند که بازپخش رسانه از راه دور، فشار دادن دکمه رسانه و سایر انواع کنش‌ها را لغو می‌کند.

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

یک کانال سفارشی اضافه کنید

برای اینکه برنامه فرستنده با برنامه گیرنده ارتباط برقرار کند، برنامه شما باید یک کانال سفارشی ایجاد کند. فرستنده می تواند از کانال سفارشی برای ارسال پیام های رشته ای به گیرنده استفاده کند. هر کانال سفارشی با یک فضای نام منحصر به فرد تعریف می شود و باید با پیشوند urn:x-cast: شروع شود، برای مثال، urn:x-cast:com.example.custom . امکان داشتن چندین کانال سفارشی وجود دارد که هر کدام دارای یک فضای نام منحصر به فرد هستند. برنامه گیرنده همچنین می تواند با استفاده از فضای نام یکسان پیام ارسال و دریافت کند .

کانال سفارشی با رابط 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);
    }
}

هنگامی که برنامه فرستنده به برنامه گیرنده متصل شد، کانال سفارشی را می توان با استفاده از روش 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);
}

پس از ایجاد کانال سفارشی، فرستنده می تواند از روش sendMessage برای ارسال پیام های رشته ای به گیرنده از طریق آن کانال استفاده کند:

کاتلین
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);
        }
    }
}

پشتیبانی از پخش خودکار

بخش APIهای پخش خودکار و صف را ببینید.

لغو انتخاب تصویر برای ویجت های UX

اجزای مختلف چارچوب (یعنی کادر گفتگوی Cast، مینی کنترلر، و UIMediaController، در صورت پیکربندی) آثار هنری را برای رسانه در حال پخش نمایش می دهند. نشانی‌های اینترنتی آثار هنری تصویر معمولاً در MediaMetadata برای رسانه گنجانده می‌شوند، اما برنامه فرستنده ممکن است یک منبع جایگزین برای URLها داشته باشد.

کلاس ImagePicker بر اساس استفاده از تصویر، به عنوان مثال، تصویر کوچک اعلان یا پس‌زمینه تمام صفحه، وسیله‌ای برای انتخاب یک تصویر مناسب از فهرست تصاویر در MediaMetadata تعریف می‌کند. پیاده‌سازی پیش‌فرض ImagePicker همیشه اولین تصویر را انتخاب می‌کند، یا اگر تصویری در MediaMetadata موجود نباشد، null را برمی‌گرداند. برنامه شما می‌تواند ImagePicker زیر کلاس قرار دهد و روش onPickImage(MediaMetadata, ImageHints) را برای ارائه یک پیاده‌سازی جایگزین لغو کند و سپس آن زیر کلاس را با روش setImagePicker CastMediaOptions.Builder انتخاب کند. ImageHints نکاتی را به ImagePicker درباره نوع و اندازه تصویری که برای نمایش در UI انتخاب می شود ارائه می دهد.

سفارشی کردن دیالوگ های Cast

مدیریت چرخه زندگی جلسه

SessionManager مکان مرکزی برای مدیریت چرخه عمر جلسه است. SessionManager به تغییرات وضعیت انتخاب مسیر Android MediaRouter برای شروع، از سرگیری و پایان جلسات گوش می دهد. هنگامی که یک مسیر انتخاب می شود، SessionManager یک شی Session ایجاد می کند و سعی می کند آن را شروع یا از سر بگیرد. هنگامی که یک مسیر انتخاب نشده است، SessionManager جلسه فعلی را پایان می دهد.

بنابراین، برای اطمینان از اینکه SessionManager چرخه های عمر جلسه را به درستی مدیریت می کند، باید مطمئن شوید که:

بسته به نحوه ایجاد گفتگوهای Cast، ممکن است لازم باشد اقدامات بیشتری انجام شود:

  • اگر دیالوگ‌های Cast را با استفاده از MediaRouteChooserDialog و MediaRouteControllerDialog ایجاد می‌کنید، این گفتگوها انتخاب مسیر را در MediaRouter به‌طور خودکار به‌روزرسانی می‌کنند، بنابراین هیچ کاری لازم نیست انجام شود.
  • اگر دکمه Cast خود را با استفاده از CastButtonFactory.setUpMediaRouteButton(Context, Menu, int) یا CastButtonFactory.setUpMediaRouteButton(Context, MediaRouteButton) تنظیم کردید، در واقع گفتگوها با استفاده از MediaRouteChooserDialog و MediaRouteControllerDialog هیچ کاری انجام نمی شود.
  • برای موارد دیگر، دیالوگ های Cast سفارشی ایجاد می کنید، بنابراین باید دستورالعمل های بالا را دنبال کنید تا وضعیت انتخاب مسیر در MediaRouter را به روز کنید.

وضعیت دستگاه صفر

اگر دیالوگ‌های Cast سفارشی ایجاد می‌کنید، MediaRouteChooserDialog سفارشی شما باید به‌درستی از مواردی که دستگاه‌های صفر پیدا شده‌اند رسیدگی کند. این گفتگو باید دارای نشانگرهایی باشد که به کاربران شما نشان دهد که چه زمانی برنامه شما همچنان در تلاش برای یافتن دستگاه‌ها است و چه زمانی تلاش کشف دیگر فعال نیست.

اگر MediaRouteChooserDialog پیش‌فرض استفاده می‌کنید، وضعیت دستگاه‌های صفر قبلاً مدیریت می‌شود.

مراحل بعدی

این ویژگی‌هایی را که می‌توانید به برنامه فرستنده Android خود اضافه کنید به پایان می‌رسد. اکنون می توانید یک برنامه فرستنده برای پلتفرم دیگری ( iOS یا Web ) بسازید یا یک برنامه گیرنده وب بسازید.