برنامه Android TV را فعال کنید

۱. مرور کلی

لوگوی گوگل کست

این آزمایشگاه کد به شما آموزش می‌دهد که چگونه یک برنامه Android TV موجود را برای پشتیبانی از پخش و ارتباط از برنامه‌های فرستنده Cast موجود خود تغییر دهید.

گوگل کست و کست کانکت چیست؟

گوگل کست به کاربران اجازه می‌دهد تا محتوا را از یک دستگاه تلفن همراه به تلویزیون منتقل کنند. یک جلسه معمولی گوگل کست از دو جزء تشکیل شده است - یک برنامه فرستنده و یک برنامه گیرنده . برنامه‌های فرستنده، مانند یک برنامه تلفن همراه یا وب‌سایتی مانند Youtube.com، پخش برنامه گیرنده کست را آغاز و کنترل می‌کنند. برنامه‌های گیرنده کست، برنامه‌های HTML 5 هستند که روی دستگاه‌های Chromecast و Android TV اجرا می‌شوند.

تقریباً تمام وضعیت یک جلسه‌ی Cast در برنامه‌ی گیرنده ذخیره می‌شود. وقتی وضعیت به‌روزرسانی می‌شود، مثلاً اگر یک آیتم رسانه‌ای جدید بارگذاری شود، وضعیت رسانه به تمام فرستنده‌ها پخش می‌شود. این پخش‌ها شامل وضعیت فعلی جلسه‌ی Cast هستند. برنامه‌های فرستنده از این وضعیت رسانه برای نمایش اطلاعات پخش در رابط کاربری خود استفاده می‌کنند.

Cast Connect بر روی این زیرساخت ساخته می‌شود و برنامه Android TV شما به عنوان گیرنده عمل می‌کند. کتابخانه Cast Connect به برنامه Android TV شما اجازه می‌دهد پیام‌ها را دریافت کند و وضعیت رسانه را پخش کند، گویی که یک برنامه گیرنده Cast است.

قرار است چه چیزی بسازیم؟

وقتی این آزمایشگاه کدنویسی را تکمیل کردید، می‌توانید از برنامه‌های فرستنده Cast برای ارسال ویدیو به یک برنامه Android TV استفاده کنید. برنامه Android TV همچنین می‌تواند از طریق پروتکل Cast با برنامه‌های فرستنده ارتباط برقرار کند.

آنچه یاد خواهید گرفت

  • نحوه اضافه کردن کتابخانه Cast Connect به یک برنامه ATV نمونه.
  • نحوه اتصال فرستنده Cast و اجرای برنامه ATV.
  • نحوه شروع پخش رسانه در برنامه ATV از طریق برنامه فرستنده Cast.
  • نحوه ارسال وضعیت رسانه از برنامه ATV به برنامه‌های فرستنده Cast.

آنچه نیاز دارید

۲. کد نمونه را دریافت کنید

شما می‌توانید تمام کدهای نمونه را روی کامپیوتر خود دانلود کنید...

و فایل زیپ دانلود شده را از حالت فشرده خارج کنید.

۳. برنامه نمونه را اجرا کنید

ابتدا، بیایید ببینیم که برنامه نمونه تکمیل شده چگونه به نظر می‌رسد. برنامه Android TV از رابط کاربری Leanback و یک پخش کننده ویدیوی ساده استفاده می‌کند. کاربر می‌تواند یک ویدیو را از لیستی انتخاب کند که در صورت انتخاب، در تلویزیون پخش می‌شود. با استفاده از برنامه فرستنده موبایل همراه، کاربر همچنین می‌تواند یک ویدیو را در برنامه Android TV پخش کند.

تصویری از مجموعه‌ای از تصاویر کوچک ویدیویی (که یکی از آنها هایلایت شده است) که پیش‌نمایش تمام‌صفحه‌ای از یک ویدیو را نشان می‌دهند؛ عبارت «Cast Connect» در بالا سمت راست ظاهر می‌شود

دستگاه‌های توسعه‌دهنده را ثبت کنید

برای فعال کردن قابلیت‌های Cast Connect برای توسعه برنامه، باید شماره سریال Google Cast دستگاه Android TV که قرار است از آن استفاده کنید را در Cast Developer Console ثبت کنید. می‌توانید شماره سریال را با رفتن به تنظیمات > تنظیمات دستگاه > Google Cast > شماره سریال در Android TV خود پیدا کنید. توجه داشته باشید که این شماره با شماره سریال دستگاه فیزیکی شما متفاوت است و باید از روشی که در بالا توضیح داده شد، دریافت شود.

تصویر صفحه نمایش تلویزیون اندروید که صفحه «Google Cast»، شماره نسخه و شماره سریال را نشان می‌دهد

بدون ثبت نام، Cast Connect به دلایل امنیتی فقط برای برنامه‌های نصب شده از فروشگاه Google Play کار می‌کند. پس از ۱۵ دقیقه از شروع فرآیند ثبت نام، دستگاه خود را مجدداً راه اندازی کنید.

برنامه فرستنده اندروید را نصب کنید

برای آزمایش ارسال درخواست از دستگاه تلفن همراه، یک برنامه فرستنده ساده به نام Cast Videos به عنوان فایل mobile-sender-0629.apk در فایل زیپ کد منبع دانلود ارائه کرده‌ایم. ما از ADB برای نصب APK استفاده خواهیم کرد. اگر قبلاً نسخه دیگری از Cast Videos را نصب کرده‌اید، لطفاً قبل از ادامه، آن نسخه را از تمام پروفایل‌های موجود در دستگاه حذف نصب کنید.

  1. گزینه‌های توسعه‌دهنده و اشکال‌زدایی USB را در گوشی اندروید خود فعال کنید .
  2. برای اتصال تلفن اندروید خود به کامپیوتر توسعه‌دهنده، یک کابل داده USB وصل کنید.
  3. mobile-sender-0629.apk را روی گوشی اندروید خود نصب کنید.

تصویر یک پنجره ترمینال که دستور adb install را برای نصب mobile-sender.apk اجرا می‌کند

  1. می‌توانید برنامه‌ی فرستنده‌ی Cast Videos را در گوشی اندروید خود پیدا کنید. نماد برنامه فرستنده ویدیوهای پخش شده

تصویر برنامه فرستنده Cast Videos که روی صفحه تلفن اندروید اجرا می‌شود

برنامه اندروید تی‌وی را نصب کنید

دستورالعمل‌های زیر نحوه باز کردن و اجرای برنامه نمونه تکمیل شده در اندروید استودیو را شرح می‌دهند:

  1. در صفحه خوشامدگویی یا از طریق منوی File > New > Import Project... گزینه Import Project را انتخاب کنید.
  2. انتخاب کنید آیکون پوشه پوشه‌ی app-done را از پوشه‌ی کد نمونه انتخاب کنید و روی تأیید کلیک کنید.
  3. روی فایل کلیک کنید > همگام‌سازی پروژه اندروید اپ استودیو با دکمه Gradle همگام‌سازی پروژه با فایل‌های Gradle
  4. گزینه‌های توسعه‌دهنده و اشکال‌زدایی USB را در دستگاه Android TV خود فعال کنید .
  5. ADB را به دستگاه اندروید تی‌وی خود متصل کنید، دستگاه باید در اندروید استودیو نمایش داده شود. تصویری که دستگاه Android TV را در نوار ابزار Android Studio نشان می‌دهد
  6. کلیک کنید دکمه‌ی اجرای اندروید استودیو، یک مثلث سبز که به سمت راست اشاره دارد دکمه‌ی اجرا (Run ) را بزنید، باید بعد از چند ثانیه برنامه‌ی ATV با نام Cast Connect Codelab را ببینید.

بیایید با برنامه ATV، Cast Connect بازی کنیم

  1. به صفحه اصلی اندروید تی‌وی بروید.
  2. برنامه‌ی ارسال‌کننده‌ی ویدیوهای کست (Cast Videos) را از گوشی اندروید خود باز کنید. روی دکمه‌ی کست (Cast) کلیک کنید. آیکون دکمه‌ی ارسال محتوا و دستگاه ATV خود را انتخاب کنید.
  3. برنامه Cast Connect Codelab ATV روی ATV شما اجرا می‌شود و دکمه Cast در فرستنده شما نشان می‌دهد که متصل شده است. آیکون دکمه ارسال محتوا با رنگ‌های معکوس .
  4. یک ویدیو را از برنامه ATV انتخاب کنید و ویدیو در ATV شما شروع به پخش خواهد کرد.
  5. در تلفن همراه شما، یک کنترلر کوچک اکنون در پایین برنامه فرستنده شما قابل مشاهده است. می‌توانید از دکمه پخش/مکث برای کنترل پخش استفاده کنید.
  6. یک ویدیو از گوشی موبایل انتخاب کنید و پخش کنید. ویدیو روی ATV شما شروع به پخش می‌کند و کنترلر باز شده روی فرستنده موبایل شما نمایش داده می‌شود.
  7. گوشی خود را قفل کنید و وقتی قفل آن را باز می‌کنید، باید اعلانی روی صفحه قفل مشاهده کنید تا پخش رسانه را کنترل کنید یا پخش را متوقف کنید.

تصویری از بخشی از صفحه نمایش یک گوشی اندروید که یک مینی‌پلیر در حال پخش ویدیو است

۴. پروژه شروع را آماده کنید

حالا که ادغام کامل برنامه با Cast Connect را تأیید کردیم، باید پشتیبانی از Cast Connect را به برنامه اولیه‌ای که دانلود کرده‌اید اضافه کنیم. حالا آماده‌اید تا با استفاده از اندروید استودیو، پروژه اولیه را بسازید:

  1. در صفحه خوشامدگویی یا از طریق منوی File > New > Import Project... گزینه Import Project را انتخاب کنید.
  2. انتخاب کنید آیکون پوشه پوشه‌ی app-start را از پوشه‌ی کد نمونه انتخاب کنید و روی تأیید کلیک کنید.
  3. روی فایل کلیک کنید > دکمه همگام‌سازی پروژه اندروید استودیو با Gradle همگام‌سازی پروژه با فایل‌های Gradle
  4. دستگاه ATV را انتخاب کنید و روی آن کلیک کنید دکمه‌ی Run در اندروید استودیو، یک مثلث سبز که به سمت راست اشاره دارد دکمه‌ی اجرا (Run) برای اجرای برنامه و بررسی رابط کاربری (UI) نوار ابزار اندروید استودیو که دستگاه اندروید تی‌وی انتخاب‌شده را نشان می‌دهد

تصویری از مجموعه‌ای از تصاویر کوچک ویدیویی (که یکی از آنها هایلایت شده است) که پیش‌نمایش تمام‌صفحه‌ای از یک ویدیو را نشان می‌دهند؛ عبارت «Cast Connect» در بالا سمت راست ظاهر می‌شود

طراحی اپلیکیشن

این برنامه لیستی از ویدیوها را برای مرور کاربر فراهم می‌کند. کاربران می‌توانند ویدیویی را برای پخش در تلویزیون اندروید انتخاب کنند. این برنامه شامل دو فعالیت اصلی است: MainActivity و PlaybackActivity .

فعالیت اصلی

این activity شامل یک Fragment ( MainFragment ) است. لیست ویدیوها و متادیتای مرتبط با آنها در کلاس MovieList پیکربندی شده و متد setupMovies() برای ساخت لیستی از اشیاء Movie فراخوانی می‌شود.

یک شیء Movie نشان‌دهنده یک موجودیت ویدیویی با عنوان، توضیحات، تصاویر کوچک و آدرس اینترنتی ویدیو است. هر شیء Movie به یک CardPresenter متصل است تا تصویر کوچک ویدیو را به همراه عنوان و استودیو نمایش دهد و به ArrayObjectAdapter منتقل می‌شود.

وقتی یک آیتم انتخاب می‌شود، شیء Movie مربوطه به PlaybackActivity ارسال می‌شود.

فعالیت پخش

این activity شامل یک Fragment ( PlaybackVideoFragment ) است که میزبان یک VideoView با ExoPlayer ، برخی کنترل‌های رسانه‌ای و یک ناحیه متنی برای نمایش توضیحات ویدیوی انتخاب شده است و به کاربر اجازه می‌دهد ویدیو را در تلویزیون اندروید پخش کند. کاربر می‌تواند از کنترل از راه دور برای پخش/مکث یا جستجوی پخش ویدیوها استفاده کند.

پیش‌نیازهای Cast Connect

Cast Connect از نسخه‌های جدید سرویس‌های Google Play استفاده می‌کند که برای استفاده از فضای نام AndroidX ، نیاز به به‌روزرسانی برنامه ATV شما دارند.

برای پشتیبانی از Cast Connect در برنامه Android TV خود، باید رویدادهایی را از یک جلسه رسانه‌ای ایجاد و پشتیبانی کنید. کتابخانه Cast Connect وضعیت رسانه را بر اساس وضعیت جلسه رسانه‌ای ایجاد می‌کند. جلسه رسانه‌ای شما همچنین توسط کتابخانه Cast Connect برای ارسال سیگنال در صورت دریافت پیام‌های خاص از یک فرستنده، مانند مکث، استفاده می‌شود.

۵. پیکربندی پشتیبانی از Cast

وابستگی‌ها

فایل build.gradle برنامه را به‌روزرسانی کنید تا وابستگی‌های کتابخانه‌ای لازم را شامل شود:

dependencies {
    ....

    // Cast Connect libraries
    implementation 'com.google.android.gms:play-services-cast-tv:20.0.0'
    implementation 'com.google.android.gms:play-services-cast:21.1.0'
}

پروژه را همگام‌سازی کنید تا ساخت پروژه بدون خطا تأیید شود.

مقداردهی اولیه

CastReceiverContext یک شیء تک‌لایه برای هماهنگی تمام تعاملات Cast است. شما باید رابط ReceiverOptionsProvider را پیاده‌سازی کنید تا CastReceiverOptions هنگام مقداردهی اولیه CastReceiverContext ارائه دهد.

فایل CastReceiverOptionsProvider.kt را ایجاد کنید و کلاس زیر را به پروژه اضافه کنید:

package com.google.sample.cast.castconnect

import android.content.Context
import com.google.android.gms.cast.tv.ReceiverOptionsProvider
import com.google.android.gms.cast.tv.CastReceiverOptions

class CastReceiverOptionsProvider : ReceiverOptionsProvider {
    override fun getOptions(context: Context): CastReceiverOptions {
        return CastReceiverOptions.Builder(context)
                .setStatusText("Cast Connect Codelab")
                .build()
    }
}

سپس ارائه دهنده گزینه‌های گیرنده را درون تگ <application> فایل AndroidManifest.xml برنامه مشخص کنید:

<application>
  ...
  <meta-data
    android:name="com.google.android.gms.cast.tv.RECEIVER_OPTIONS_PROVIDER_CLASS_NAME"
    android:value="com.google.sample.cast.castconnect.CastReceiverOptionsProvider" />
</application>

برای اتصال به برنامه ATV خود از طریق فرستنده Cast، فعالیتی را که می‌خواهید اجرا کنید انتخاب کنید. در این آزمایشگاه کد، MainActivity برنامه را هنگام شروع یک جلسه Cast اجرا خواهیم کرد. در فایل AndroidManifest.xml ، فیلتر launch intent را در MainActivity اضافه کنید.

<activity android:name=".MainActivity">
  ...
  <intent-filter>
    <action android:name="com.google.android.gms.cast.tv.action.LAUNCH" />
    <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
</activity>

چرخه حیات زمینه گیرنده Cast

شما باید CastReceiverContext هنگام اجرای برنامه شروع کنید و CastReceiverContext را هنگام انتقال برنامه به پس‌زمینه متوقف کنید. توصیه می‌کنیم از LifecycleObserver از کتابخانه androidx.lifecycle برای مدیریت فراخوانی CastReceiverContext.start() و CastReceiverContext.stop() استفاده کنید.

فایل MyApplication.kt را باز کنید، زمینه تبدیل (cast context) را با فراخوانی initInstance() در متد onCreate برنامه، مقداردهی اولیه کنید. در کلاس AppLifeCycleObserver CastReceiverContext هنگام از سرگیری برنامه start() و هنگام مکث برنامه stop() :

package com.google.sample.cast.castconnect

import com.google.android.gms.cast.tv.CastReceiverContext
...

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        CastReceiverContext.initInstance(this)
        ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifecycleObserver())
    }

    class AppLifecycleObserver : DefaultLifecycleObserver {
        override fun onResume(owner: LifecycleOwner) {
            Log.d(LOG_TAG, "onResume")
            CastReceiverContext.getInstance().start()
        }

        override fun onPause(owner: LifecycleOwner) {
            Log.d(LOG_TAG, "onPause")
            CastReceiverContext.getInstance().stop()
        }
    }
}

اتصال MediaSession به MediaManager

MediaManager یک ویژگی از Singleton مربوط به CastReceiverContext است که وضعیت رسانه را مدیریت می‌کند، قصد بارگذاری را مدیریت می‌کند، پیام‌های فضای نام رسانه را از فرستنده‌ها به دستورات رسانه‌ای ترجمه می‌کند و وضعیت رسانه را به فرستنده‌ها ارسال می‌کند.

وقتی یک MediaSession ایجاد می‌کنید، باید توکن MediaSession فعلی را نیز به MediaManager ارائه دهید تا بداند دستورات را به کجا ارسال کند و وضعیت پخش رسانه را بازیابی کند. در فایل PlaybackVideoFragment.kt ، قبل از تنظیم توکن روی MediaManager ، مطمئن شوید که MediaSession مقداردهی اولیه شده است.

import com.google.android.gms.cast.tv.CastReceiverContext
import com.google.android.gms.cast.tv.media.MediaManager
...

class PlaybackVideoFragment : VideoSupportFragment() {
    private var castReceiverContext: CastReceiverContext? = null
    ...

    private fun initializePlayer() {
        if (mPlayer == null) {
            ...
            mMediaSession = MediaSessionCompat(getContext(), LOG_TAG)
            ...
            castReceiverContext = CastReceiverContext.getInstance()
            if (castReceiverContext != null) {
                val mediaManager: MediaManager = castReceiverContext!!.getMediaManager()
                mediaManager.setSessionCompatToken(mMediaSession!!.getSessionToken())
            }

        }
    }
}

وقتی MediaSession خود را به دلیل پخش غیرفعال آزاد می‌کنید، باید یک توکن null روی MediaManager تنظیم کنید:

private fun releasePlayer() {
    mMediaSession?.release()
    castReceiverContext?.mediaManager?.setSessionCompatToken(null)
    ...
}

بیایید برنامه نمونه را اجرا کنیم

کلیک کنید دکمه‌ی Run در اندروید استودیو، یک مثلث سبز که به سمت راست اشاره دارد دکمه اجرا را برای اجرای برنامه روی دستگاه ATV خود فشار دهید، برنامه را ببندید و به صفحه اصلی ATV برگردید. از فرستنده خود، روی دکمه ارسال (Cast) کلیک کنید. آیکون دکمه‌ی ارسال محتوا و دستگاه ATV خود را انتخاب کنید. خواهید دید که برنامه ATV روی دستگاه ATV اجرا شده و وضعیت دکمه Cast متصل است.

۶. بارگذاری رسانه

دستور بارگذاری (load) از طریق یک intent با نام پکیجی که در کنسول توسعه‌دهنده تعریف کرده‌اید، ارسال می‌شود. شما باید فیلتر intent از پیش تعریف‌شده‌ی زیر را در برنامه‌ی Android TV خود اضافه کنید تا activity هدفی که این intent را دریافت خواهد کرد، مشخص شود. در فایل AndroidManifest.xml ، فیلتر intent بارگذاری را به PlayerActivity اضافه کنید:

<activity android:name="com.google.sample.cast.castconnect.PlaybackActivity"
          android:launchMode="singleTask"
          android:exported="true">
  <intent-filter>
     <action android:name="com.google.android.gms.cast.tv.action.LOAD"/>
     <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
</activity>

مدیریت درخواست‌های بارگذاری در اندروید تی‌وی

اکنون که اکتیویتی برای دریافت این intent حاوی درخواست بارگذاری پیکربندی شده است، باید آن را مدیریت کنیم.

برنامه هنگام شروع فعالیت، یک متد خصوصی به نام processIntent را فراخوانی می‌کند. این متد شامل منطق پردازش intentهای ورودی است. برای مدیریت درخواست بارگذاری، این متد را تغییر داده و intent را برای پردازش بیشتر با فراخوانی متد onNewIntent از نمونه MediaManager ارسال می‌کنیم. اگر MediaManager تشخیص دهد که intent یک درخواست بارگذاری است، شیء MediaLoadRequestData را از intent استخراج کرده و MediaLoadCommandCallback.onLoad() را فراخوانی می‌کند. متد processIntent را در فایل PlaybackVideoFragment.kt تغییر دهید تا intent حاوی درخواست بارگذاری را مدیریت کند:

fun processIntent(intent: Intent?) {
    val mediaManager: MediaManager = CastReceiverContext.getInstance().getMediaManager()
    // Pass intent to Cast SDK
    if (mediaManager.onNewIntent(intent)) {
        return
    }

    // Clears all overrides in the modifier.
    mediaManager.getMediaStatusModifier().clear()

    // If the SDK doesn't recognize the intent, handle the intent with your own logic.
    ...
}

در مرحله بعد، کلاس انتزاعی MediaLoadCommandCallback را بسط می‌دهیم که متد onLoad() فراخوانی شده توسط MediaManager را لغو می‌کند. این متد داده‌های درخواست بارگذاری را دریافت کرده و آن را به یک شیء Movie تبدیل می‌کند. پس از تبدیل، فیلم توسط پخش‌کننده محلی پخش می‌شود. سپس MediaManager با MediaLoadRequest به‌روزرسانی می‌شود و MediaStatus را به فرستنده‌های متصل پخش می‌کند. یک کلاس خصوصی تو در تو به نام MyMediaLoadCommandCallback در فایل PlaybackVideoFragment.kt ایجاد کنید:

import com.google.android.gms.cast.MediaLoadRequestData
import com.google.android.gms.cast.MediaInfo
import com.google.android.gms.cast.MediaMetadata
import com.google.android.gms.cast.MediaError
import com.google.android.gms.cast.tv.media.MediaException
import com.google.android.gms.cast.tv.media.MediaCommandCallback
import com.google.android.gms.cast.tv.media.QueueUpdateRequestData
import com.google.android.gms.cast.tv.media.MediaLoadCommandCallback
import com.google.android.gms.tasks.Task
import com.google.android.gms.tasks.Tasks
import android.widget.Toast
...

private inner class MyMediaLoadCommandCallback :  MediaLoadCommandCallback() {
    override fun onLoad(
        senderId: String?, mediaLoadRequestData: MediaLoadRequestData): Task<MediaLoadRequestData> {
        Toast.makeText(activity, "onLoad()", Toast.LENGTH_SHORT).show()
        return if (mediaLoadRequestData == null) {
            // Throw MediaException to indicate load failure.
            Tasks.forException(MediaException(
                MediaError.Builder()
                    .setDetailedErrorCode(MediaError.DetailedErrorCode.LOAD_FAILED)
                    .setReason(MediaError.ERROR_REASON_INVALID_REQUEST)
                    .build()))
        } else Tasks.call {
            play(convertLoadRequestToMovie(mediaLoadRequestData)!!)
            // Update media metadata and state
            val mediaManager = castReceiverContext!!.mediaManager
            mediaManager.setDataFromLoad(mediaLoadRequestData)
            mediaLoadRequestData
        }
    }
}

private fun convertLoadRequestToMovie(mediaLoadRequestData: MediaLoadRequestData?): Movie? {
    if (mediaLoadRequestData == null) {
        return null
    }
    val mediaInfo: MediaInfo = mediaLoadRequestData.getMediaInfo() ?: return null
    var videoUrl: String = mediaInfo.getContentId()
    if (mediaInfo.getContentUrl() != null) {
        videoUrl = mediaInfo.getContentUrl()
    }
    val metadata: MediaMetadata = mediaInfo.getMetadata()
    val movie = Movie()
    movie.videoUrl = videoUrl
    movie.title = metadata?.getString(MediaMetadata.KEY_TITLE)
    movie.description = metadata?.getString(MediaMetadata.KEY_SUBTITLE)
    if(metadata?.hasImages() == true) {
        movie.cardImageUrl = metadata.images[0].url.toString()
    }
    return movie
}

حالا که Callback تعریف شده است، باید آن را در MediaManager ثبت کنیم. این callback باید قبل از فراخوانی MediaManager.onNewIntent() ثبت شود. setMediaLoadCommandCallback را هنگام مقداردهی اولیه پخش‌کننده اضافه کنید:

private fun initializePlayer() {
    if (mPlayer == null) {
        ...
        mMediaSession = MediaSessionCompat(getContext(), LOG_TAG)
        ...
        castReceiverContext = CastReceiverContext.getInstance()
        if (castReceiverContext != null) {
            val mediaManager: MediaManager = castReceiverContext.getMediaManager()
            mediaManager.setSessionCompatToken(mMediaSession.getSessionToken())
            mediaManager.setMediaLoadCommandCallback(MyMediaLoadCommandCallback())
        }
    }
}

بیایید برنامه نمونه را اجرا کنیم

کلیک کنید دکمه‌ی Run در اندروید استودیو، یک مثلث سبز که به سمت راست اشاره دارد دکمه اجرا (Run) را برای اجرای برنامه روی دستگاه ATV خود فشار دهید. از فرستنده خود، روی دکمه ارسال (Cast) کلیک کنید. آیکون دکمه‌ی ارسال محتوا و دستگاه ATV خود را انتخاب کنید. برنامه ATV روی دستگاه ATV اجرا خواهد شد. یک ویدیو را در موبایل انتخاب کنید، ویدیو روی ATV شروع به پخش خواهد کرد. بررسی کنید که آیا در تلفن خود اعلانی مبنی بر وجود کنترل‌های پخش دریافت می‌کنید یا خیر. سعی کنید از کنترل‌هایی مانند مکث استفاده کنید، ویدیو روی دستگاه ATV باید مکث شود.

۷. پشتیبانی از دستورات کنترل Cast

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

وقتی پخش‌کننده مقداردهی اولیه شد، با استفاده از setMediaCommandCallback MyMediaCommandCallback به نمونه MediaManager اضافه کنید:

private fun initializePlayer() {
    ...
    castReceiverContext = CastReceiverContext.getInstance()
    if (castReceiverContext != null) {
        val mediaManager = castReceiverContext!!.mediaManager
        ...
        mediaManager.setMediaCommandCallback(MyMediaCommandCallback())
    }
}

کلاس MyMediaCommandCallback را برای لغو متدهایی مانند onQueueUpdate() ایجاد کنید تا از دستورات کنترل Cast پشتیبانی کند:

private inner class MyMediaCommandCallback : MediaCommandCallback() {
    override fun onQueueUpdate(
        senderId: String?,
        queueUpdateRequestData: QueueUpdateRequestData
    ): Task<Void> {
        Toast.makeText(getActivity(), "onQueueUpdate()", Toast.LENGTH_SHORT).show()
        // Queue Prev / Next
        if (queueUpdateRequestData.getJump() != null) {
            Toast.makeText(
                getActivity(),
                "onQueueUpdate(): Jump = " + queueUpdateRequestData.getJump(),
                Toast.LENGTH_SHORT
            ).show()
        }
        return super.onQueueUpdate(senderId, queueUpdateRequestData)
    }
}

۸. کار با وضعیت رسانه

تغییر وضعیت رسانه

Cast Connect وضعیت رسانه پایه را از جلسه رسانه دریافت می‌کند. برای پشتیبانی از ویژگی‌های پیشرفته، برنامه Android TV شما می‌تواند از طریق MediaStatusModifier ، ویژگی‌های وضعیت اضافی را مشخص و لغو کند. MediaStatusModifier همیشه روی MediaSession که در CastReceiverContext تنظیم کرده‌اید، عمل خواهد کرد.

برای مثال، برای مشخص کردن setMediaCommandSupported هنگام فعال شدن فراخوانی onLoad :

import com.google.android.gms.cast.MediaStatus
...
private class MyMediaLoadCommandCallback : MediaLoadCommandCallback() {
    fun onLoad(
        senderId: String?,
        mediaLoadRequestData: MediaLoadRequestData
    ): Task<MediaLoadRequestData> {
        Toast.makeText(getActivity(), "onLoad()", Toast.LENGTH_SHORT).show()
        ...
        return Tasks.call({
            play(convertLoadRequestToMovie(mediaLoadRequestData)!!)
            ...
            // Use MediaStatusModifier to provide additional information for Cast senders.
            mediaManager.getMediaStatusModifier()
                .setMediaCommandSupported(MediaStatus.COMMAND_QUEUE_NEXT, true)
                .setIsPlayingAd(false)
            mediaManager.broadcastMediaStatus()
            // Return the resolved MediaLoadRequestData to indicate load success.
            mediaLoadRequestData
        })
    }
}

رهگیری وضعیت رسانه قبل از ارسال

مشابه MessageInterceptor در کیت توسعه وب گیرنده SDK، می‌توانید یک MediaStatusWriter در MediaManager خود مشخص کنید تا قبل از پخش MediaStatus به فرستندگان متصل، تغییرات اضافی را در آن اعمال کند.

برای مثال، می‌توانید قبل از ارسال به فرستندگان موبایل، داده‌های سفارشی را در MediaStatus تنظیم کنید:

import com.google.android.gms.cast.tv.media.MediaManager.MediaStatusInterceptor
import com.google.android.gms.cast.tv.media.MediaStatusWriter
import org.json.JSONObject
import org.json.JSONException
...

private fun initializePlayer() {
    if (mPlayer == null) {
        ...
        if (castReceiverContext != null) {
            ...
            val mediaManager: MediaManager = castReceiverContext.getMediaManager()
            ...
            // Use MediaStatusInterceptor to process the MediaStatus before sending out.
            mediaManager.setMediaStatusInterceptor(
                MediaStatusInterceptor { mediaStatusWriter: MediaStatusWriter ->
                    try {
                        mediaStatusWriter.setCustomData(JSONObject("{myData: 'CustomData'}"))
                    } catch (e: JSONException) {
                        Log.e(LOG_TAG,e.message,e);
                    }
            })
        }
    }
}        

۹. تبریک

اکنون می‌دانید که چگونه با استفاده از کتابخانه Cast Connect، قابلیت Cast را در یک برنامه Android TV فعال کنید.

برای جزئیات بیشتر به راهنمای توسعه‌دهنده نگاهی بیندازید: /cast/docs/android_tv_receiver .