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

وقفه‌های تبلیغاتی

کیت توسعه نرم‌افزاری فرستنده اندروید (Android Sender SDK) از نمایش تبلیغات لحظه‌ای (Ad Breaks) و تبلیغات همراه در یک جریان رسانه‌ای مشخص پشتیبانی می‌کند.

برای اطلاعات بیشتر در مورد نحوه عملکرد Ad Breakها، به مرور کلی Ad Breakهای گیرنده وب مراجعه کنید.

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

در اندروید، با استفاده از 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، در صورت پیکربندی) طرح گرافیکی مربوط به رسانه‌ی در حال پخش فعلی را نمایش می‌دهند. URLهای مربوط به طرح گرافیکی تصویر معمولاً در MediaMetadata مربوط به رسانه گنجانده شده‌اند، اما برنامه‌ی فرستنده ممکن است منبع جایگزینی برای URLها داشته باشد.

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

سفارشی‌سازی پنجره‌های محاوره‌ای Cast

مدیریت چرخه حیات جلسه

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

بنابراین، برای اطمینان از اینکه SessionManager چرخه حیات session را به درستی مدیریت می‌کند، باید مطمئن شوید که:

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

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

حالت صفر دستگاه

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

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

مراحل بعدی

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