یک برنامه اندرویدی را Cast فعال کنید

1. بررسی اجمالی

نشان‌واره Google Cast

این کد لبه به شما می آموزد که چگونه یک برنامه ویدیویی موجود در اندروید را برای ارسال محتوا در یک دستگاه دارای Google Cast تغییر دهید.

Google Cast چیست؟

Google Cast به کاربران امکان می دهد محتوا را از دستگاه تلفن همراه به تلویزیون ارسال کنند. سپس کاربران می توانند از دستگاه تلفن همراه خود به عنوان یک کنترل از راه دور برای پخش رسانه در تلویزیون استفاده کنند.

Google Cast SDK به شما امکان می دهد برنامه خود را برای کنترل تلویزیون یا سیستم صوتی گسترش دهید. Cast SDK به شما امکان می دهد اجزای رابط کاربری لازم را بر اساس چک لیست طراحی Google Cast اضافه کنید.

چک لیست طراحی Google Cast برای ساده و قابل پیش بینی کردن تجربه کاربر Cast در همه پلتفرم های پشتیبانی شده ارائه شده است.

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

پس از تکمیل این کد لبه، یک برنامه ویدیویی Android خواهید داشت که می‌تواند ویدیوها را به دستگاهی با قابلیت Google Cast ارسال کند.

چیزی که یاد خواهید گرفت

  • چگونه Google Cast SDK را به یک برنامه ویدیویی نمونه اضافه کنیم.
  • نحوه اضافه کردن دکمه Cast برای انتخاب دستگاه Google Cast.
  • نحوه اتصال به دستگاه Cast و راه اندازی گیرنده رسانه.
  • نحوه پخش ویدیو
  • چگونه مینی کنترلر Cast را به برنامه خود اضافه کنید.
  • نحوه پشتیبانی از اعلان‌های رسانه و کنترل‌های صفحه قفل
  • نحوه اضافه کردن یک کنترلر توسعه یافته
  • نحوه ارائه یک پوشش مقدماتی
  • چگونه ویجت‌های Cast را سفارشی کنیم.
  • نحوه ادغام با Cast Connect

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

  • جدیدترین Android SDK .
  • اندروید استودیو نسخه 3.2+
  • یک دستگاه تلفن همراه با Android 4.1+ Jelly Bean (سطح API 16).
  • یک کابل داده USB برای اتصال دستگاه تلفن همراه به رایانه توسعه.
  • یک دستگاه Google Cast مانند Chromecast یا Android TV که با دسترسی به اینترنت پیکربندی شده است.
  • تلویزیون یا مانیتور با ورودی HDMI.
  • برای آزمایش ادغام Cast Connect به Chromecast با Google TV نیاز است، اما برای بقیه Codelab اختیاری است. اگر یکی ندارید، در پایان این آموزش از مرحله Add Cast Connect Support رد شوید.

تجربه کنید

  • شما باید دانش قبلی کاتلین و توسعه اندروید را داشته باشید.
  • شما همچنین به دانش قبلی در مورد تماشای تلویزیون نیاز دارید :)

چگونه از این آموزش استفاده خواهید کرد؟

فقط از طریق آن را بخوانید آن را بخوانید و تمرینات را کامل کنید

به تجربه خود از ساخت اپلیکیشن های اندرویدی چه امتیازی می دهید؟

تازه کار متوسط مسلط

تجربه خود را از تماشای تلویزیون چگونه ارزیابی می کنید؟

تازه کار متوسط مسلط

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

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

و فایل فشرده دانلود شده را باز کنید.

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

نماد یک جفت قطب نما

ابتدا، بیایید ببینیم که برنامه نمونه تکمیل شده چگونه به نظر می رسد. این برنامه یک پخش کننده ویدیوی اساسی است. کاربر می تواند یک ویدیو را از یک لیست انتخاب کند و سپس می تواند ویدیو را به صورت محلی در دستگاه پخش کند یا آن را به دستگاه Google Cast ارسال کند.

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

Import Project را در صفحه خوش آمدگویی یا گزینه های منو File > New > Import Project... را انتخاب کنید.

را انتخاب کنید نماد پوشه دایرکتوری app-done از پوشه کد نمونه و روی OK کلیک کنید.

روی فایل > کلیک کنید دکمه «Sync Project with Gradle» اندروید استودیو همگام سازی پروژه با فایل های Gradle .

اشکال زدایی USB را در دستگاه Android خود فعال کنید - در اندروید 4.2 و بالاتر، صفحه گزینه های برنامه نویس به طور پیش فرض پنهان است. برای اینکه آن را قابل مشاهده کنید، به Settings > About phone بروید و هفت بار روی Build number ضربه بزنید. به صفحه قبلی بازگردید، به System > Advanced بروید و روی Developer options نزدیک پایین ضربه بزنید، سپس روی USB debugging ضربه بزنید تا روشن شود.

دستگاه اندروید خود را وصل کنید و روی آن کلیک کنید دکمه اجرای اندروید استودیو، یک مثلث سبز رنگ که به سمت راست اشاره می کند دکمه اجرا در اندروید استودیو. پس از چند ثانیه باید ببینید که برنامه ویدیویی با نام Cast Videos ظاهر می شود.

روی دکمه Cast در برنامه ویدیو کلیک کنید و دستگاه Google Cast خود را انتخاب کنید.

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

پخش ویدیو در دستگاه Google Cast شما شروع می شود.

کنترل کننده گسترش یافته نمایش داده می شود. می توانید از دکمه پخش/مکث برای کنترل پخش استفاده کنید.

به لیست ویدیوها برگردید.

اکنون یک مینی کنترلر در پایین صفحه قابل مشاهده است. تصویری از یک تلفن اندرویدی که برنامه «Cast Videos» را اجرا می‌کند و مینی کنترلر در پایین صفحه ظاهر می‌شود.

روی دکمه مکث در کنترلر کوچک کلیک کنید تا ویدیو روی گیرنده متوقف شود. برای ادامه پخش مجدد ویدیو، روی دکمه پخش در مینی کنترلر کلیک کنید.

روی دکمه هوم دستگاه موبایل کلیک کنید. اعلان‌ها را پایین بکشید و اکنون باید یک اعلان برای جلسه Cast ببینید.

تلفن خود را قفل کنید و وقتی قفل آن را باز می کنید، باید اعلانی را روی صفحه قفل مشاهده کنید تا پخش رسانه را کنترل کنید یا ارسال را متوقف کنید.

به برنامه ویدیو برگردید و روی دکمه Cast کلیک کنید تا ارسال محتوا در دستگاه Google Cast متوقف شود.

سوالات متداول

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

تصویری از یک تلفن Android که برنامه «Cast Videos» را اجرا می‌کند

باید پشتیبانی از Google Cast را به برنامه شروعی که دانلود کردید اضافه کنیم. در اینجا برخی از اصطلاحات Google Cast وجود دارد که در این لبه کد استفاده خواهیم کرد:

  • یک برنامه فرستنده روی دستگاه تلفن همراه یا لپ تاپ اجرا می شود،
  • یک برنامه گیرنده در دستگاه Google Cast اجرا می شود.

اکنون شما آماده هستید تا با استفاده از Android Studio روی پروژه شروع کننده ایجاد کنید:

  1. را انتخاب کنید نماد پوشه دایرکتوری app-start از دانلود کد نمونه خود ( وارد کردن پروژه را در صفحه خوش آمدگویی یا گزینه منو File > New > Import Project... را انتخاب کنید).
  2. را کلیک کنید دکمه «Sync Project with Gradle» اندروید استودیو همگام سازی پروژه با دکمه Gradle Files .
  3. را کلیک کنید دکمه اجرای اندروید استودیو، یک مثلث سبز رنگ که به سمت راست اشاره می کند دکمه اجرا برای اجرای برنامه و کاوش در رابط کاربری.

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

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

این برنامه از دو فعالیت اصلی تشکیل شده است: VideoBrowserActivity و LocalPlayerActivity . برای ادغام عملکرد Google Cast، Activities باید از AppCompatActivity یا از والد آن FragmentActivity به ارث برده شود. این محدودیت وجود دارد زیرا ما باید MediaRouteButton (ارائه شده در کتابخانه پشتیبانی MediaRouter ) را به عنوان MediaRouteActionProvider اضافه کنیم و این فقط در صورتی کار می کند که فعالیت از کلاس های ذکر شده در بالا به ارث برده شود. کتابخانه پشتیبانی MediaRouter به کتابخانه پشتیبانی AppCompat بستگی دارد که کلاس های مورد نیاز را ارائه می دهد.

VideoBrowserActivity

این فعالیت حاوی یک Fragment ( VideoBrowserFragment ) است. این لیست توسط یک ArrayAdapter ( VideoListAdapter ) پشتیبانی می شود. لیست ویدیوها و ابرداده مرتبط با آنها در یک سرور راه دور به عنوان یک فایل JSON میزبانی می شود. یک AsyncTaskLoader ( VideoItemLoader ) این JSON را واکشی می کند و آن را پردازش می کند تا لیستی از اشیاء MediaItem بسازد.

یک شی MediaItem یک ویدیو و ابرداده مرتبط با آن، مانند عنوان، توضیحات، URL برای جریان، URL برای تصاویر پشتیبان، و تراک‌های متن مرتبط (برای زیرنویس‌ها) در صورت وجود، مدل می‌کند. شی MediaItem بین اکتیویتی ها ارسال می شود، بنابراین MediaItem روش های کاربردی برای تبدیل آن به Bundle و بالعکس دارد.

هنگامی که لودر لیست MediaItems را می سازد، آن لیست را به VideoListAdapter ارسال می کند که سپس لیست MediaItems را در VideoBrowserFragment ارائه می کند. به کاربر لیستی از تصاویر کوچک ویدیو با توضیحات کوتاه برای هر ویدیو ارائه می شود. هنگامی که یک مورد انتخاب می شود، MediaItem مربوطه به یک Bundle تبدیل می شود و به LocalPlayerActivity ارسال می شود.

LocalPlayerActivity

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

این فعالیت میزبان یک VideoView ، برخی از کنترل‌های رسانه، و یک ناحیه متنی برای نمایش توضیحات ویدیوی انتخابی است. پخش کننده قسمت بالای صفحه را پوشش می دهد و فضایی را برای توضیحات دقیق ویدیو در زیر باز می کند. کاربر می تواند پخش/مکث کند یا به دنبال پخش محلی ویدیوها باشد.

وابستگی ها

از آنجایی که ما از AppCompatActivity استفاده می کنیم، به کتابخانه پشتیبانی AppCompat نیاز داریم. برای مدیریت لیست ویدیوها و دریافت ناهمزمان تصاویر لیست، از کتابخانه Volley استفاده می کنیم.

سوالات متداول

5. افزودن دکمه Cast

تصویر قسمت بالای یک تلفن Android با اجرای برنامه Cast Video. دکمه Cast که در گوشه سمت راست بالای صفحه ظاهر می شود

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

وابستگی ها

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

dependencies {
    implementation 'androidx.appcompat:appcompat:1.5.0'
    implementation 'androidx.mediarouter:mediarouter:1.3.1'
    implementation 'androidx.recyclerview:recyclerview:1.2.1'
    implementation 'com.google.android.gms:play-services-cast-framework:21.1.0'
    implementation 'com.android.volley:volley:1.2.1'
    implementation "androidx.core:core-ktx:1.8.0"
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}

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

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

چارچوب Cast دارای یک شی تک‌تنی جهانی به CastContext است که همه تعاملات Cast را هماهنگ می‌کند.

شما باید رابط OptionsProvider را برای تامین CastOptions مورد نیاز برای مقداردهی اولیه CastContext singleton پیاده سازی کنید. مهمترین گزینه شناسه برنامه گیرنده است که برای فیلتر کردن نتایج کشف دستگاه Cast و راه اندازی برنامه گیرنده هنگام شروع جلسه Cast استفاده می شود.

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

فایل جدید CastOptionsProvider.kt زیر را به بسته com.google.sample.cast.refplayer پروژه اضافه کنید:

package com.google.sample.cast.refplayer

import android.content.Context
import com.google.android.gms.cast.framework.OptionsProvider
import com.google.android.gms.cast.framework.CastOptions
import com.google.android.gms.cast.framework.SessionProvider

class CastOptionsProvider : OptionsProvider {
    override fun getCastOptions(context: Context): CastOptions {
        return CastOptions.Builder()
                .setReceiverApplicationId(context.getString(R.string.app_id))
                .build()
    }

    override fun getAdditionalSessionProviders(context: Context): List<SessionProvider>? {
        return null
    }
}

اکنون OptionsProvider در تگ " application " برنامه AndroidManifest.xml اعلام کنید:

<meta-data
    android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
    android:value="com.google.sample.cast.refplayer.CastOptionsProvider" />

با تنبلی CastContext را در متد VideoBrowserActivity onCreate مقداردهی کنید:

import com.google.android.gms.cast.framework.CastContext

private var mCastContext: CastContext? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.video_browser)
    setupActionBar()

    mCastContext = CastContext.getSharedInstance(this)
}

همان منطق اولیه سازی را به LocalPlayerActivity اضافه کنید.

دکمه Cast

اکنون که CastContext مقداردهی اولیه شده است، باید دکمه Cast را اضافه کنیم تا کاربر بتواند یک دستگاه Cast را انتخاب کند. دکمه Cast توسط MediaRouteButton از کتابخانه پشتیبانی MediaRouter پیاده سازی شده است. مانند هر نماد عملی که می توانید به فعالیت خود اضافه کنید (با استفاده از ActionBar یا Toolbar )، ابتدا باید آیتم منوی مربوطه را به منوی خود اضافه کنید.

فایل res/menu/browse.xml را ویرایش کنید و آیتم MediaRouteActionProvider را در منو قبل از آیتم تنظیمات اضافه کنید:

<item
    android:id="@+id/media_route_menu_item"
    android:title="@string/media_route_menu_title"
    app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
    app:showAsAction="always"/>

با استفاده از CastButtonFactory برای اتصال MediaRouteButton به چارچوب Cast، روش onCreateOptionsMenu() از VideoBrowserActivity نادیده بگیرید:

import com.google.android.gms.cast.framework.CastButtonFactory

private var mediaRouteMenuItem: MenuItem? = null

override fun onCreateOptionsMenu(menu: Menu): Boolean {
     super.onCreateOptionsMenu(menu)
     menuInflater.inflate(R.menu.browse, menu)
     mediaRouteMenuItem = CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), menu,
                R.id.media_route_menu_item)
     return true
}

به روشی مشابه، onCreateOptionsMenu در LocalPlayerActivity لغو کنید.

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

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

6. پخش محتوای ویدیویی

تصویری از یک تلفن Android که برنامه «Cast Videos» را اجرا می‌کند

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

رسانه ریخته گری

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

  1. یک شی MediaInfo ایجاد کنید که یک آیتم رسانه را مدل می کند.
  2. به دستگاه Cast متصل شوید و برنامه گیرنده خود را راه اندازی کنید.
  3. شی MediaInfo را در گیرنده خود بارگذاری کنید و محتوا را پخش کنید.
  4. وضعیت رسانه را پیگیری کنید.
  5. دستورات پخش را بر اساس تعاملات کاربر به گیرنده ارسال کنید.

ما قبلاً مرحله 2 را در بخش قبل انجام داده ایم. انجام مرحله 3 با چارچوب Cast آسان است. مرحله 1 معادل نگاشت یک شی به شی دیگر است. MediaInfo چیزی است که چارچوب Cast آن را درک می کند و MediaItem محفظه برنامه ما برای یک آیتم رسانه است. ما به راحتی می توانیم یک MediaItem را به MediaInfo نگاشت کنیم.

برنامه نمونه LocalPlayerActivity از قبل با استفاده از این فهرست، بین پخش محلی و از راه دور تمایز قائل می شود:

private var mLocation: PlaybackLocation? = null

enum class PlaybackLocation {
    LOCAL, REMOTE
}

enum class PlaybackState {
    PLAYING, PAUSED, BUFFERING, IDLE
}

در این کد لبه برای شما مهم نیست که بدانید دقیقاً چگونه منطق پخش کننده نمونه کار می کند. درک این نکته مهم است که پخش کننده رسانه برنامه شما باید اصلاح شود تا از دو مکان پخش به روشی مشابه آگاه باشد.

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

مدیریت جلسه بازیگران

برای چارچوب Cast، یک جلسه Cast مراحل اتصال به یک دستگاه، راه‌اندازی (یا پیوستن)، اتصال به یک برنامه گیرنده، و راه‌اندازی یک کانال کنترل رسانه را در صورت لزوم ترکیب می‌کند. کانال کنترل رسانه نحوه ارسال و دریافت پیام‌ها از پخش‌کننده رسانه گیرنده توسط چارچوب Cast است.

وقتی کاربر دستگاهی را از روی دکمه Cast انتخاب می‌کند، جلسه Cast به‌طور خودکار شروع می‌شود و وقتی کاربر ارتباط خود را قطع می‌کند، به‌طور خودکار متوقف می‌شود. اتصال مجدد به جلسه گیرنده به دلیل مشکلات شبکه نیز به طور خودکار توسط Cast SDK انجام می شود.

بیایید یک SessionManagerListener به LocalPlayerActivity اضافه کنیم:

import com.google.android.gms.cast.framework.CastSession
import com.google.android.gms.cast.framework.SessionManagerListener
...

private var mSessionManagerListener: SessionManagerListener<CastSession>? = null
private var mCastSession: CastSession? = null
...

private fun setupCastListener() {
    mSessionManagerListener = object : SessionManagerListener<CastSession> {
        override fun onSessionEnded(session: CastSession, error: Int) {
            onApplicationDisconnected()
        }

        override fun onSessionResumed(session: CastSession, wasSuspended: Boolean) {
            onApplicationConnected(session)
        }

        override fun onSessionResumeFailed(session: CastSession, error: Int) {
            onApplicationDisconnected()
        }

        override fun onSessionStarted(session: CastSession, sessionId: String) {
            onApplicationConnected(session)
        }

        override fun onSessionStartFailed(session: CastSession, error: Int) {
            onApplicationDisconnected()
        }

        override fun onSessionStarting(session: CastSession) {}
        override fun onSessionEnding(session: CastSession) {}
        override fun onSessionResuming(session: CastSession, sessionId: String) {}
        override fun onSessionSuspended(session: CastSession, reason: Int) {}
        private fun onApplicationConnected(castSession: CastSession) {
            mCastSession = castSession
            if (null != mSelectedMedia) {
                if (mPlaybackState == PlaybackState.PLAYING) {
                    mVideoView!!.pause()
                    loadRemoteMedia(mSeekbar!!.progress, true)
                    return
                } else {
                    mPlaybackState = PlaybackState.IDLE
                    updatePlaybackLocation(PlaybackLocation.REMOTE)
                }
            }
            updatePlayButton(mPlaybackState)
            invalidateOptionsMenu()
        }

        private fun onApplicationDisconnected() {
            updatePlaybackLocation(PlaybackLocation.LOCAL)
            mPlaybackState = PlaybackState.IDLE
            mLocation = PlaybackLocation.LOCAL
            updatePlayButton(mPlaybackState)
            invalidateOptionsMenu()
       }
   }
}

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

جلسه فعال فعلی با نام SessionManager.getCurrentSession() قابل دسترسی است. در پاسخ به تعامل کاربر با گفتگوهای Cast، جلسات به طور خودکار ایجاد و حذف می شوند.

ما باید شنود جلسه خود را ثبت کنیم و برخی از متغیرهایی را که در اکتیویتی استفاده خواهیم کرد مقداردهی اولیه کنیم. متد LocalPlayerActivity onCreate را به:

import com.google.android.gms.cast.framework.CastContext
...

private var mCastContext: CastContext? = null
...

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    mCastContext = CastContext.getSharedInstance(this)
    mCastSession = mCastContext!!.sessionManager.currentCastSession
    setupCastListener()
    ...
    loadViews()
    ...
    val bundle = intent.extras
    if (bundle != null) {
        ....
        if (shouldStartPlayback) {
              ....

        } else {
            if (mCastSession != null && mCastSession!!.isConnected()) {
                updatePlaybackLocation(PlaybackLocation.REMOTE)
            } else {
                updatePlaybackLocation(PlaybackLocation.LOCAL)
            }
            mPlaybackState = PlaybackState.IDLE
            updatePlayButton(mPlaybackState)
        }
    }
    ...
}

در حال بارگیری رسانه

در Cast SDK، RemoteMediaClient مجموعه‌ای از APIهای راحت را برای مدیریت پخش رسانه از راه دور در گیرنده فراهم می‌کند. برای CastSession که از پخش رسانه پشتیبانی می کند، یک نمونه از RemoteMediaClient به طور خودکار توسط SDK ایجاد می شود. با فراخوانی متد getRemoteMediaClient() در نمونه CastSession قابل دسترسی است. روش‌های زیر را به LocalPlayerActivity اضافه کنید تا ویدیوی انتخابی فعلی را روی گیرنده بارگیری کنید:

import com.google.android.gms.cast.framework.media.RemoteMediaClient
import com.google.android.gms.cast.MediaInfo
import com.google.android.gms.cast.MediaLoadOptions
import com.google.android.gms.cast.MediaMetadata
import com.google.android.gms.common.images.WebImage
import com.google.android.gms.cast.MediaLoadRequestData

private fun loadRemoteMedia(position: Int, autoPlay: Boolean) {
    if (mCastSession == null) {
        return
    }
    val remoteMediaClient = mCastSession!!.remoteMediaClient ?: return
    remoteMediaClient.load( MediaLoadRequestData.Builder()
                .setMediaInfo(buildMediaInfo())
                .setAutoplay(autoPlay)
                .setCurrentTime(position.toLong()).build())
}

private fun buildMediaInfo(): MediaInfo? {
    val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE)
    mSelectedMedia?.studio?.let { movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, it) }
    mSelectedMedia?.title?.let { movieMetadata.putString(MediaMetadata.KEY_TITLE, it) }
    movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia!!.getImage(0))))
    movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia!!.getImage(1))))
    return mSelectedMedia!!.url?.let {
        MediaInfo.Builder(it)
            .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
            .setContentType("videos/mp4")
            .setMetadata(movieMetadata)
            .setStreamDuration((mSelectedMedia!!.duration * 1000).toLong())
            .build()
    }
}

اکنون روش‌های مختلف موجود را به‌روزرسانی کنید تا از منطق جلسه Cast برای پشتیبانی از پخش از راه دور استفاده کنید:

private fun play(position: Int) {
    startControllersTimer()
    when (mLocation) {
        PlaybackLocation.LOCAL -> {
            mVideoView!!.seekTo(position)
            mVideoView!!.start()
        }
        PlaybackLocation.REMOTE -> {
            mPlaybackState = PlaybackState.BUFFERING
            updatePlayButton(mPlaybackState)
            //seek to a new position within the current media item's new position 
            //which is in milliseconds from the beginning of the stream
            mCastSession!!.remoteMediaClient?.seek(position.toLong())
        }
        else -> {}
    }
    restartTrickplayTimer()
}
private fun togglePlayback() {
    ...
    PlaybackState.IDLE -> when (mLocation) {
        ...
        PlaybackLocation.REMOTE -> {
            if (mCastSession != null && mCastSession!!.isConnected) {
                loadRemoteMedia(mSeekbar!!.progress, true)
            }
        }
        else -> {}
    }
    ...
}
override fun onPause() {
    ...
    mCastContext!!.sessionManager.removeSessionManagerListener(
                mSessionManagerListener!!, CastSession::class.java)
}
override fun onResume() {
    Log.d(TAG, "onResume() was called")
    mCastContext!!.sessionManager.addSessionManagerListener(
            mSessionManagerListener!!, CastSession::class.java)
    if (mCastSession != null && mCastSession!!.isConnected) {
        updatePlaybackLocation(PlaybackLocation.REMOTE)
    } else {
        updatePlaybackLocation(PlaybackLocation.LOCAL)
    }
    super.onResume()
}

برای متد updatePlayButton ، مقدار متغیر isConnected را تغییر دهید:

private fun updatePlayButton(state: PlaybackState?) {
    ...
    val isConnected = (mCastSession != null
                && (mCastSession!!.isConnected || mCastSession!!.isConnecting))
    ...
}

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

7. مینی کنترلر

چک لیست طراحی Cast مستلزم آن است که همه برنامه‌های Cast یک کنترل‌کننده کوچک ارائه دهند که وقتی کاربر از صفحه محتوای فعلی دور می‌شود ظاهر شود. مینی کنترلر دسترسی فوری و یک یادآوری قابل مشاهده را برای جلسه Cast فعلی فراهم می کند.

تصویر قسمت پایینی تلفن Android که پخش کننده کوچک را در برنامه Cast Videos نشان می دهد

Cast SDK یک نمای سفارشی، MiniControllerFragment ارائه می‌کند، که می‌تواند به فایل طرح‌بندی برنامه فعالیت‌هایی که می‌خواهید کنترل‌کننده کوچک را در آنها نشان دهید اضافه شود.

تعریف قطعه زیر را به پایین هر دو res/layout/player_activity.xml و res/layout/video_browser.xml اضافه کنید:

<fragment
    android:id="@+id/castMiniController"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:visibility="gone"
    class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment"/>

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

8. اعلان و صفحه قفل

چک لیست طراحی Google Cast به یک برنامه فرستنده نیاز دارد تا کنترل‌های رسانه را از یک اعلان و صفحه قفل اجرا کند.

تصویر یک تلفن Android که کنترل‌های رسانه را در قسمت اعلان‌ها نشان می‌دهد

Cast SDK یک MediaNotificationService برای کمک به برنامه فرستنده در ساخت کنترل‌های رسانه برای اعلان و صفحه قفل ارائه می‌کند. این سرویس به صورت خودکار در مانیفست برنامه شما ادغام می شود.

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

هنگام تنظیم اولیه CastContext کنترل‌های اعلان و صفحه قفل را می‌توان با CastOptions فعال کرد. کنترل های رسانه برای اعلان و صفحه قفل به طور پیش فرض روشن هستند. تا زمانی که اعلان روشن باشد، ویژگی صفحه قفل روشن است.

CastOptionsProvider را ویرایش کنید و پیاده سازی getCastOptions را برای مطابقت با این کد تغییر دهید:

import com.google.android.gms.cast.framework.media.CastMediaOptions
import com.google.android.gms.cast.framework.media.NotificationOptions

override fun getCastOptions(context: Context): CastOptions {
   val notificationOptions = NotificationOptions.Builder()
            .setTargetActivityClassName(VideoBrowserActivity::class.java.name)
            .build()
    val mediaOptions = CastMediaOptions.Builder()
            .setNotificationOptions(notificationOptions)
            .build()
   return CastOptions.Builder()
                .setReceiverApplicationId(context.getString(R.string.app_id))
                .setCastMediaOptions(mediaOptions)
                .build()
}

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

تصویر یک تلفن Android که کنترل‌های رسانه را روی صفحه قفل نشان می‌دهد

9. پوشش مقدماتی

چک لیست طراحی Google Cast به یک برنامه فرستنده نیاز دارد تا دکمه Cast را به کاربران فعلی معرفی کند تا به آنها اطلاع دهد که برنامه فرستنده اکنون از ارسال محتوا پشتیبانی می کند و همچنین به کاربران تازه وارد Google Cast کمک می کند.

تصویری که پوشش مقدماتی Cast را در اطراف دکمه Cast در برنامه Cast Videos Android نشان می‌دهد

Cast SDK یک نمای سفارشی به IntroductoryOverlay را ارائه می دهد که می تواند برای برجسته کردن دکمه Cast در اولین نمایش داده شدن به کاربران استفاده شود. کد زیر را به VideoBrowserActivity اضافه کنید:

import com.google.android.gms.cast.framework.IntroductoryOverlay
import android.os.Looper

private var mIntroductoryOverlay: IntroductoryOverlay? = null

private fun showIntroductoryOverlay() {
    mIntroductoryOverlay?.remove()
    if (mediaRouteMenuItem?.isVisible == true) {
       Looper.myLooper().run {
           mIntroductoryOverlay = com.google.android.gms.cast.framework.IntroductoryOverlay.Builder(
                    this@VideoBrowserActivity, mediaRouteMenuItem!!)
                   .setTitleText("Introducing Cast")
                   .setSingleTime()
                   .setOnOverlayDismissedListener(
                           object : IntroductoryOverlay.OnOverlayDismissedListener {
                               override fun onOverlayDismissed() {
                                   mIntroductoryOverlay = null
                               }
                          })
                   .build()
          mIntroductoryOverlay!!.show()
        }
    }
}

اکنون، یک CastStateListener اضافه کنید و onPause که یک دستگاه Cast در دسترس است onCreate onResume showIntroductoryOverlay را فراخوانی کنید.

import com.google.android.gms.cast.framework.CastState
import com.google.android.gms.cast.framework.CastStateListener

private var mCastStateListener: CastStateListener? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.video_browser)
    setupActionBar()
    mCastStateListener = object : CastStateListener {
            override fun onCastStateChanged(newState: Int) {
                if (newState != CastState.NO_DEVICES_AVAILABLE) {
                    showIntroductoryOverlay()
                }
            }
        }
    mCastContext = CastContext.getSharedInstance(this)
}

override fun onResume() {
    super.onResume()
    mCastContext?.addCastStateListener(mCastStateListener!!)
}

override fun onPause() {
    super.onPause()
    mCastContext?.removeCastStateListener(mCastStateListener!!)
}

داده های برنامه را پاک کنید یا برنامه را از دستگاه خود حذف کنید. سپس، روی دکمه اجرای اندروید استودیو، یک مثلث سبز رنگ که به سمت راست اشاره می کند دکمه اجرا برای اجرای برنامه در دستگاه تلفن همراه خود و باید پوشش مقدماتی را مشاهده کنید (اگر همپوشانی نمایش داده نشد، داده های برنامه را پاک کنید).

10. کنترل کننده گسترش یافته

چک‌لیست طراحی Google Cast به یک برنامه فرستنده نیاز دارد تا کنترل‌کننده گسترده‌ای را برای رسانه در حال پخش فراهم کند. کنترلر توسعه یافته یک نسخه تمام صفحه از مینی کنترلر است.

تصویری از یک ویدیو در حال پخش در تلفن اندرویدی که کنترلر گسترش یافته روی آن قرار گرفته است

Cast SDK ویجتی را برای کنترلر توسعه یافته به نام ExpandedControllerActivity فراهم می کند. این یک کلاس انتزاعی است که برای اضافه کردن دکمه Cast باید آن را زیر کلاس قرار دهید.

ابتدا یک فایل منبع منوی جدید به نام expanded_controller.xml ایجاد کنید تا کنترلر توسعه یافته دکمه Cast را ارائه دهد:

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
            android:id="@+id/media_route_menu_item"
            android:title="@string/media_route_menu_title"
            app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
            app:showAsAction="always"/>

</menu>

یک بسته جدید expandedcontrols در بسته com.google.sample.cast.refplayer ایجاد کنید. سپس یک فایل جدید به نام ExpandedControlsActivity.kt در بسته com.google.sample.cast.refplayer.expandedcontrols ایجاد کنید.

package com.google.sample.cast.refplayer.expandedcontrols

import android.view.Menu
import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity
import com.google.sample.cast.refplayer.R
import com.google.android.gms.cast.framework.CastButtonFactory

class ExpandedControlsActivity : ExpandedControllerActivity() {
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        super.onCreateOptionsMenu(menu)
        menuInflater.inflate(R.menu.expanded_controller, menu)
        CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item)
        return true
    }
}

اکنون ExpandedControlsActivity را در AndroidManifest.xml در تگ application بالای OPTIONS_PROVIDER_CLASS_NAME اعلام کنید:

<application>
    ...
    <activity
        android:name="com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity"
        android:label="@string/app_name"
        android:launchMode="singleTask"
        android:theme="@style/Theme.CastVideosDark"
        android:screenOrientation="portrait"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
        </intent-filter>
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.google.sample.cast.refplayer.VideoBrowserActivity"/>
    </activity>
    ...
</application>

CastOptionsProvider را ویرایش کنید و NotificationOptions و CastMediaOptions تغییر دهید تا فعالیت هدف را روی ExpandedControlsActivity تنظیم کنید:

import com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity

override fun getCastOptions(context: Context): CastOptions {
    val notificationOptions = NotificationOptions.Builder()
            .setTargetActivityClassName(ExpandedControlsActivity::class.java.name)
            .build()
    val mediaOptions = CastMediaOptions.Builder()
            .setNotificationOptions(notificationOptions)
            .setExpandedControllerActivityClassName(ExpandedControlsActivity::class.java.name)
            .build()
    return CastOptions.Builder()
            .setReceiverApplicationId(context.getString(R.string.app_id))
            .setCastMediaOptions(mediaOptions)
            .build()
}

روش LocalPlayerActivity loadRemoteMedia را برای نمایش ExpandedControlsActivity هنگام بارگیری رسانه راه دور به روز کنید:

import com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity

private fun loadRemoteMedia(position: Int, autoPlay: Boolean) {
    if (mCastSession == null) {
        return
    }
    val remoteMediaClient = mCastSession!!.remoteMediaClient ?: return
    remoteMediaClient.registerCallback(object : RemoteMediaClient.Callback() {
        override fun onStatusUpdated() {
            val intent = Intent(this@LocalPlayerActivity, ExpandedControlsActivity::class.java)
            startActivity(intent)
            remoteMediaClient.unregisterCallback(this)
        }
    })
    remoteMediaClient.load(MediaLoadRequestData.Builder()
                .setMediaInfo(buildMediaInfo())
                .setAutoplay(autoPlay)
                .setCurrentTime(position.toLong()).build())
}

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

11. پشتیبانی Cast Connect را اضافه کنید

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

وابستگی ها

توجه: برای اجرای Cast Connect، play-services-cast-framework باید 19.0.0 یا بالاتر باشد.

گزینه های راه اندازی

برای راه‌اندازی برنامه Android TV که به آن گیرنده Android نیز گفته می‌شود، باید پرچم setAndroidReceiverCompatible را در شی LaunchOptions روی true تنظیم کنیم. این شی LaunchOptions نحوه راه اندازی گیرنده را دیکته می کند و به CastOptions ارسال شده توسط کلاس CastOptionsProvider ارسال می شود. با تنظیم پرچم ذکر شده در بالا روی false ، گیرنده وب برای شناسه برنامه تعریف شده در کنسول توسعه دهنده Cast راه اندازی می شود.

در فایل CastOptionsProvider.kt موارد زیر را به متد getCastOptions اضافه کنید:

import com.google.android.gms.cast.LaunchOptions
...
val launchOptions = LaunchOptions.Builder()
            .setAndroidReceiverCompatible(true)
            .build()
return new CastOptions.Builder()
        .setLaunchOptions(launchOptions)
        ...
        .build()

اعتبار راه اندازی را تنظیم کنید

در سمت فرستنده، می‌توانید CredentialsData برای نشان دادن افرادی که به جلسه می‌پیوندند، مشخص کنید. credentials رشته ای است که می تواند توسط کاربر تعریف شود، تا زمانی که برنامه ATV شما بتواند آن را درک کند. CredentialsData فقط در زمان راه‌اندازی یا زمان پیوستن به برنامه Android TV شما منتقل می‌شود. اگر در حین اتصال دوباره آن را تنظیم کنید، به برنامه Android TV شما منتقل نخواهد شد.

برای تنظیم Launch Credentials CredentialsData باید تعریف شده و به شی LaunchOptions ارسال شود. کد زیر را به متد getCastOptions در فایل CastOptionsProvider.kt خود اضافه کنید:

import com.google.android.gms.cast.CredentialsData
...

val credentialsData = CredentialsData.Builder()
        .setCredentials("{\"userId\": \"abc\"}")
        .build()
val launchOptions = LaunchOptions.Builder()
       ...
       .setCredentialsData(credentialsData)
       .build()

اعتبارنامه ها را در LoadRequest تنظیم کنید

در صورتی که برنامه گیرنده وب و برنامه Android TV شما credentials به طور متفاوتی مدیریت می کنند، ممکن است لازم باشد برای هر کدام credentials جداگانه تعریف کنید. برای مراقبت از آن، کد زیر را در فایل LocalPlayerActivity.kt خود در تابع loadRemoteMedia اضافه کنید:

remoteMediaClient.load(MediaLoadRequestData.Builder()
       ...
       .setCredentials("user-credentials")
       .setAtvCredentials("atv-user-credentials")
       .build())

بسته به برنامه گیرنده‌ای که فرستنده شما به آن ارسال می‌کند، SDK اکنون به‌طور خودکار بررسی می‌کند که از کدام اعتبارنامه‌ها برای جلسه جاری استفاده کند.

آزمایش Cast Connect

مراحل نصب Android TV APK در Chromecast با Google TV

  1. آدرس IP دستگاه Android TV خود را پیدا کنید. معمولاً در تنظیمات > شبکه و اینترنت > (نام شبکه ای که دستگاه شما به آن متصل است) موجود است. در سمت راست، جزئیات و IP دستگاه شما را در شبکه نشان می دهد.
  2. از آدرس IP دستگاه خود برای اتصال از طریق ADB با استفاده از ترمینال به آن استفاده کنید:
$ adb connect <device_ip_address>:5555
  1. از پنجره ترمینال خود، به پوشه سطح بالا برای نمونه‌های Codelab که در ابتدای این کد لبه دانلود کرده‌اید، بروید. به عنوان مثال:
$ cd Desktop/android_codelab_src
  1. فایل apk. را در این پوشه در Android TV خود با اجرای:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. اکنون باید بتوانید برنامه ای به نام Cast Videos را در منوی برنامه های شما در دستگاه Android TV خود مشاهده کنید.
  2. به پروژه Android Studio خود بازگردید و روی دکمه Run کلیک کنید تا برنامه فرستنده را در دستگاه تلفن همراه فیزیکی خود نصب و اجرا کنید. در گوشه سمت راست بالا، روی نماد Cast کلیک کنید و دستگاه Android TV خود را از گزینه‌های موجود انتخاب کنید. اکنون باید برنامه Android TV را مشاهده کنید که در دستگاه Android TV شما راه اندازی شده است و پخش یک ویدیو به شما امکان می دهد تا با استفاده از کنترل از راه دور Android TV خود، پخش ویدیو را کنترل کنید.

12. ویجت های Cast را سفارشی کنید

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

res/values/styles_castvideo.xml را به روز کنید

<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
    ...
    <item name="mediaRouteTheme">@style/CustomMediaRouterTheme</item>
    <item name="castIntroOverlayStyle">@style/CustomCastIntroOverlay</item>
    <item name="castMiniControllerStyle">@style/CustomCastMiniController</item>
    <item name="castExpandedControllerStyle">@style/CustomCastExpandedController</item>
    <item name="castExpandedControllerToolbarStyle">
        @style/ThemeOverlay.AppCompat.ActionBar
    </item>
    ...
</style>

تم های سفارشی زیر را اعلام کنید:

<!-- Customize Cast Button -->
<style name="CustomMediaRouterTheme" parent="Theme.MediaRouter">
    <item name="mediaRouteButtonStyle">@style/CustomMediaRouteButtonStyle</item>
</style>
<style name="CustomMediaRouteButtonStyle" parent="Widget.MediaRouter.Light.MediaRouteButton">
    <item name="mediaRouteButtonTint">#EEFF41</item>
</style>

<!-- Customize Introductory Overlay -->
<style name="CustomCastIntroOverlay" parent="CastIntroOverlay">
    <item name="castButtonTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Button</item>
    <item name="castTitleTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Title</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Button" parent="android:style/TextAppearance">
    <item name="android:textColor">#FFFFFF</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Title" parent="android:style/TextAppearance.Large">
    <item name="android:textColor">#FFFFFF</item>
</style>

<!-- Customize Mini Controller -->
<style name="CustomCastMiniController" parent="CastMiniController">
    <item name="castShowImageThumbnail">true</item>
    <item name="castTitleTextAppearance">@style/TextAppearance.AppCompat.Subhead</item>
    <item name="castSubtitleTextAppearance">@style/TextAppearance.AppCompat.Caption</item>
    <item name="castBackground">@color/accent</item>
    <item name="castProgressBarColor">@color/orange</item>
</style>

<!-- Customize Expanded Controller -->
<style name="CustomCastExpandedController" parent="CastExpandedController">
    <item name="castButtonColor">#FFFFFF</item>
    <item name="castPlayButtonDrawable">@drawable/cast_ic_expanded_controller_play</item>
    <item name="castPauseButtonDrawable">@drawable/cast_ic_expanded_controller_pause</item>
    <item name="castStopButtonDrawable">@drawable/cast_ic_expanded_controller_stop</item>
</style>

13. تبریک می گویم

اکنون می‌دانید که چگونه یک برنامه ویدیویی را با استفاده از ابزارک‌های Cast SDK در Android فعال کنید.

برای جزئیات بیشتر، به راهنمای برنامه‌نویس Android Sender مراجعه کنید.

،

1. بررسی اجمالی

نشان‌واره Google Cast

این کد لبه به شما می آموزد که چگونه یک برنامه ویدیویی موجود در اندروید را برای ارسال محتوا در یک دستگاه دارای Google Cast تغییر دهید.

Google Cast چیست؟

Google Cast به کاربران امکان می دهد محتوا را از دستگاه تلفن همراه به تلویزیون ارسال کنند. سپس کاربران می توانند از دستگاه تلفن همراه خود به عنوان یک کنترل از راه دور برای پخش رسانه در تلویزیون استفاده کنند.

Google Cast SDK به شما امکان می دهد برنامه خود را برای کنترل تلویزیون یا سیستم صوتی گسترش دهید. Cast SDK به شما امکان می دهد اجزای رابط کاربری لازم را بر اساس چک لیست طراحی Google Cast اضافه کنید.

چک لیست طراحی Google Cast برای ساده و قابل پیش بینی کردن تجربه کاربر Cast در همه پلتفرم های پشتیبانی شده ارائه شده است.

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

پس از تکمیل این کد لبه، یک برنامه ویدیویی Android خواهید داشت که می‌تواند ویدیوها را به دستگاهی با قابلیت Google Cast ارسال کند.

چیزی که یاد خواهید گرفت

  • چگونه Google Cast SDK را به یک برنامه ویدیویی نمونه اضافه کنیم.
  • نحوه اضافه کردن دکمه Cast برای انتخاب دستگاه Google Cast.
  • نحوه اتصال به دستگاه Cast و راه اندازی گیرنده رسانه.
  • نحوه پخش ویدیو
  • چگونه مینی کنترلر Cast را به برنامه خود اضافه کنید.
  • نحوه پشتیبانی از اعلان‌های رسانه و کنترل‌های صفحه قفل
  • نحوه اضافه کردن یک کنترلر توسعه یافته
  • نحوه ارائه یک پوشش مقدماتی
  • چگونه ویجت‌های Cast را سفارشی کنیم.
  • نحوه ادغام با Cast Connect

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

  • جدیدترین Android SDK .
  • اندروید استودیو نسخه 3.2+
  • یک دستگاه تلفن همراه با Android 4.1+ Jelly Bean (سطح API 16).
  • یک کابل داده USB برای اتصال دستگاه تلفن همراه به رایانه توسعه.
  • یک دستگاه Google Cast مانند Chromecast یا Android TV که با دسترسی به اینترنت پیکربندی شده است.
  • تلویزیون یا مانیتور با ورودی HDMI.
  • برای آزمایش ادغام Cast Connect به Chromecast با Google TV نیاز است، اما برای بقیه Codelab اختیاری است. اگر یکی ندارید، در پایان این آموزش از مرحله Add Cast Connect Support رد شوید.

تجربه کنید

  • شما باید دانش قبلی کاتلین و توسعه اندروید را داشته باشید.
  • شما همچنین به دانش قبلی در مورد تماشای تلویزیون نیاز دارید :)

چگونه از این آموزش استفاده خواهید کرد؟

فقط از طریق آن را بخوانید آن را بخوانید و تمرینات را کامل کنید

به تجربه خود از ساخت اپلیکیشن های اندرویدی چه امتیازی می دهید؟

تازه کار متوسط مسلط

تجربه خود را از تماشای تلویزیون چگونه ارزیابی می کنید؟

تازه کار متوسط مسلط

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

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

و فایل فشرده دانلود شده را باز کنید.

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

نماد یک جفت قطب نما

ابتدا، بیایید ببینیم که برنامه نمونه تکمیل شده چگونه به نظر می رسد. این برنامه یک پخش کننده ویدیوی اساسی است. کاربر می تواند یک ویدیو را از یک لیست انتخاب کند و سپس می تواند ویدیو را به صورت محلی در دستگاه پخش کند یا آن را به دستگاه Google Cast ارسال کند.

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

Import Project را در صفحه خوش آمدگویی یا گزینه های منو File > New > Import Project... را انتخاب کنید.

را انتخاب کنید نماد پوشه دایرکتوری app-done از پوشه کد نمونه و روی OK کلیک کنید.

روی فایل > کلیک کنید دکمه «Sync Project with Gradle» اندروید استودیو همگام سازی پروژه با فایل های Gradle .

اشکال زدایی USB را در دستگاه Android خود فعال کنید - در اندروید 4.2 و بالاتر، صفحه گزینه های برنامه نویس به طور پیش فرض پنهان است. برای اینکه آن را قابل مشاهده کنید، به Settings > About phone بروید و هفت بار روی Build number ضربه بزنید. به صفحه قبلی بازگردید، به System > Advanced بروید و روی Developer options نزدیک پایین ضربه بزنید، سپس روی USB debugging ضربه بزنید تا روشن شود.

دستگاه اندروید خود را وصل کنید و روی آن کلیک کنید دکمه اجرای اندروید استودیو، یک مثلث سبز رنگ که به سمت راست اشاره می کند دکمه اجرا در اندروید استودیو. پس از چند ثانیه باید ببینید که برنامه ویدیویی با نام Cast Videos ظاهر می شود.

روی دکمه Cast در برنامه ویدیو کلیک کنید و دستگاه Google Cast خود را انتخاب کنید.

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

پخش ویدیو در دستگاه Google Cast شما شروع می شود.

کنترل کننده گسترش یافته نمایش داده می شود. می توانید از دکمه پخش/مکث برای کنترل پخش استفاده کنید.

به لیست ویدیوها برگردید.

اکنون یک مینی کنترلر در پایین صفحه قابل مشاهده است. تصویری از یک تلفن اندرویدی که برنامه «Cast Videos» را اجرا می‌کند و مینی کنترلر در پایین صفحه ظاهر می‌شود.

روی دکمه مکث در کنترلر کوچک کلیک کنید تا ویدیو روی گیرنده متوقف شود. برای ادامه پخش مجدد ویدیو، روی دکمه پخش در مینی کنترلر کلیک کنید.

روی دکمه هوم دستگاه موبایل کلیک کنید. اعلان‌ها را پایین بکشید و اکنون باید یک اعلان برای جلسه Cast ببینید.

تلفن خود را قفل کنید و وقتی قفل آن را باز می کنید، باید اعلانی را روی صفحه قفل مشاهده کنید تا پخش رسانه را کنترل کنید یا ارسال را متوقف کنید.

به برنامه ویدیو برگردید و روی دکمه Cast کلیک کنید تا ارسال محتوا در دستگاه Google Cast متوقف شود.

سوالات متداول

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

تصویری از یک تلفن Android که برنامه «Cast Videos» را اجرا می‌کند

باید پشتیبانی از Google Cast را به برنامه شروعی که دانلود کردید اضافه کنیم. در اینجا برخی از اصطلاحات Google Cast وجود دارد که در این لبه کد استفاده خواهیم کرد:

  • یک برنامه فرستنده روی دستگاه تلفن همراه یا لپ تاپ اجرا می شود،
  • یک برنامه گیرنده در دستگاه Google Cast اجرا می شود.

اکنون شما آماده ساخت در بالای پروژه استارت با استفاده از Android Studio هستید:

  1. را انتخاب کنید نماد پوشه دایرکتوری app-start از بارگیری کد نمونه خود (وارد کردن پروژه واردات در صفحه Welcome یا File> New> Import Project ... گزینه منو).
  2. کلیک بر روی دکمه Android Studio 'Sync با دکمه Gradle' پروژه همگام سازی با دکمه Gradle Files .
  3. کلیک بر روی دکمه اجرا Android Studio ، یک مثلث سبز که به سمت راست نشان می دهد دکمه را اجرا کنید تا برنامه را اجرا کنید و UI را کاوش کنید.

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

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

این برنامه از دو فعالیت اصلی تشکیل شده است: VideoBrowserActivity و LocalPlayerActivity . به منظور ادغام عملکرد بازیگران Google ، فعالیت ها باید از طریق AppCompatActivity یا والدین آن FragmentActivity شوند. این محدودیت وجود دارد از آنجا که ما نیاز به اضافه کردن MediaRouteButton (ارائه شده در کتابخانه پشتیبانی Mediarouter ) به عنوان یک MediaRouteActionProvider داریم و این تنها در صورتی که فعالیت از کلاسهای فوق الذکر باشد ، کار خواهد کرد. کتابخانه پشتیبانی Mediarouter به کتابخانه پشتیبانی AppCompat بستگی دارد که کلاسهای مورد نیاز را ارائه می دهد.

VideoBrowseractivity

این فعالیت شامل یک Fragment ( VideoBrowserFragment ) است. این لیست توسط ArrayAdapter ( VideoListAdapter ) پشتیبانی می شود. لیست فیلم ها و ابرداده های مرتبط با آنها به عنوان یک فایل JSON در یک سرور از راه دور میزبانی می شوند. یک AsyncTaskLoader ( VideoItemLoader ) این JSON را واگذار می کند و آن را برای ساختن لیستی از اشیاء MediaItem پردازش می کند.

یک شیء MediaItem یک فیلم و ابرداده مرتبط با آن ، مانند عنوان ، توضیحات ، URL برای جریان ، URL برای تصاویر پشتیبانی و آهنگ های متن مرتبط (برای زیرنویس های بسته) را در صورت وجود مدل می کند. شیء MediaItem بین فعالیت ها منتقل می شود ، بنابراین MediaItem روش های ابزار برای تبدیل آن به یک Bundle و برعکس دارد.

هنگامی که لودر لیست MediaItems را ایجاد می کند ، آن لیست را به VideoListAdapter منتقل می کند که سپس لیست MediaItems را در VideoBrowserFragment ارائه می دهد. کاربر با لیستی از تصاویر کوچک ویدیویی با توضیحات کوتاه برای هر ویدیو ارائه شده است. هنگامی که یک مورد انتخاب می شود ، MediaItem مربوطه به یک Bundle تبدیل می شود و به LocalPlayerActivity منتقل می شود.

فعالیت محلی

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

این فعالیت میزبان یک VideoView ، برخی از کنترل رسانه ها و یک منطقه متنی برای نشان دادن توضیحات ویدیوی انتخاب شده است. پخش کننده قسمت بالای صفحه را پوشش می دهد و اتاق را برای توضیحات دقیق فیلم در زیر می گذارد. کاربر می تواند بازی/مکث کند یا به دنبال پخش محلی فیلم ها باشد.

وابستگی ها

از آنجا که ما از AppCompatActivity استفاده می کنیم ، به کتابخانه پشتیبانی AppCompat احتیاج داریم. برای مدیریت لیست فیلم ها و به طور غیر همزمان گرفتن تصاویر برای لیست ، ما از کتابخانه واللی استفاده می کنیم.

سوالات متداول

5. اضافه کردن دکمه بازیگران

تصویر قسمت بالای یک تلفن اندرویدی با برنامه ویدیویی بازیگران در حال اجرا است. دکمه بازیگران در گوشه سمت راست بالای صفحه ظاهر می شود

یک برنامه با قابلیت ریخته گری دکمه بازیگران را در هر یک از فعالیت های خود نشان می دهد. با کلیک بر روی دکمه Cast، لیستی از دستگاه‌های Cast که کاربر می‌تواند انتخاب کند، نمایش داده می‌شود. اگر کاربر در دستگاه فرستنده محتوا را به صورت محلی پخش می کرد، انتخاب دستگاه Cast پخش را در آن دستگاه Cast شروع یا از سر می گیرد. در هر زمان در طول جلسه بازیگران ، کاربر می تواند روی دکمه CAST کلیک کرده و برنامه ریزی خود را به دستگاه بازیگران متوقف کند. کاربر باید در هر فعالیتی از برنامه شما ، همانطور که در لیست چک طراحی Google Cast توضیح داده شده است ، از دستگاه بازیگران وصل یا جدا شود.

وابستگی ها

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

dependencies {
    implementation 'androidx.appcompat:appcompat:1.5.0'
    implementation 'androidx.mediarouter:mediarouter:1.3.1'
    implementation 'androidx.recyclerview:recyclerview:1.2.1'
    implementation 'com.google.android.gms:play-services-cast-framework:21.1.0'
    implementation 'com.android.volley:volley:1.2.1'
    implementation "androidx.core:core-ktx:1.8.0"
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}

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

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

چارچوب بازیگران دارای یک شیء Singleton جهانی ، CastContext است که همه تعامل بازیگران را هماهنگ می کند.

شما باید رابط OptionsProvider را برای تهیه CastOptions مورد نیاز برای اولیه سازی Singleton CastContext پیاده سازی کنید. مهمترین گزینه شناسه برنامه گیرنده است که برای فیلتر کردن نتایج کشف دستگاه بازیگران و راه اندازی برنامه گیرنده هنگام شروع جلسه بازیگران استفاده می شود.

هنگامی که برنامه خود را با قابلیت بازیگران خود تهیه می کنید ، باید به عنوان یک توسعه دهنده بازیگران ثبت نام کنید و سپس شناسه برنامه را برای برنامه خود بدست آورید. برای این CodeLab ، ما از یک شناسه برنامه نمونه استفاده خواهیم کرد.

پرونده جدید CastOptionsProvider.kt را به بسته com.google.sample.cast.refplayer از پروژه اضافه کنید:

package com.google.sample.cast.refplayer

import android.content.Context
import com.google.android.gms.cast.framework.OptionsProvider
import com.google.android.gms.cast.framework.CastOptions
import com.google.android.gms.cast.framework.SessionProvider

class CastOptionsProvider : OptionsProvider {
    override fun getCastOptions(context: Context): CastOptions {
        return CastOptions.Builder()
                .setReceiverApplicationId(context.getString(R.string.app_id))
                .build()
    }

    override fun getAdditionalSessionProviders(context: Context): List<SessionProvider>? {
        return null
    }
}

اکنون OptionsProvider در برچسب " application " برنامه AndroidManifest.xml اعلام کنید:

<meta-data
    android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
    android:value="com.google.sample.cast.refplayer.CastOptionsProvider" />

CastContext در روش onCreate VideoBrowserActivity به صورت تنبیه کنید:

import com.google.android.gms.cast.framework.CastContext

private var mCastContext: CastContext? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.video_browser)
    setupActionBar()

    mCastContext = CastContext.getSharedInstance(this)
}

همان منطق اولیه سازی را به LocalPlayerActivity اضافه کنید.

دکمه بازیگران

اکنون که CastContext اولیه سازی شده است ، باید دکمه CAST را اضافه کنیم تا به کاربر اجازه دهد یک دستگاه ریخته گری را انتخاب کند. دکمه بازیگران توسط MediaRouteButton از کتابخانه پشتیبانی Mediarouter اجرا شده است. مانند هر نماد اکشن که می توانید به فعالیت خود اضافه کنید (با استفاده از یک ActionBar یا Toolbar ) ، ابتدا باید مورد منوی مربوطه را به منوی خود اضافه کنید.

پرونده res/menu/browse.xml را ویرایش کرده و مورد MediaRouteActionProvider را در منو قبل از مورد تنظیمات اضافه کنید:

<item
    android:id="@+id/media_route_menu_item"
    android:title="@string/media_route_menu_title"
    app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
    app:showAsAction="always"/>

روش onCreateOptionsMenu() VideoBrowserActivity با استفاده از CastButtonFactory برای سیم کشی MediaRouteButton به چارچوب بازیگران نادیده بگیرید:

import com.google.android.gms.cast.framework.CastButtonFactory

private var mediaRouteMenuItem: MenuItem? = null

override fun onCreateOptionsMenu(menu: Menu): Boolean {
     super.onCreateOptionsMenu(menu)
     menuInflater.inflate(R.menu.browse, menu)
     mediaRouteMenuItem = CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), menu,
                R.id.media_route_menu_item)
     return true
}

onCreateOptionsMenu در LocalPlayerActivity به روشی مشابه نادیده بگیرید.

کلیک بر روی دکمه اجرا Android Studio ، یک مثلث سبز که به سمت راست نشان می دهد دکمه را اجرا کنید تا برنامه را روی دستگاه تلفن همراه خود اجرا کنید. شما باید یک دکمه بازیگران را در نوار اکشن برنامه مشاهده کنید و وقتی روی آن کلیک می کنید ، دستگاه های بازیگران را در شبکه محلی خود لیست می کند. کشف دستگاه به طور خودکار توسط CastContext اداره می شود. دستگاه ریخته گری خود را انتخاب کنید و برنامه گیرنده نمونه بر روی دستگاه ریخته گری بارگیری می شود. می توانید بین فعالیت مرور و فعالیت پخش کننده محلی حرکت کنید و وضعیت دکمه بازیگران در همگام سازی نگه داشته می شود.

ما هیچ پشتیبانی از پخش رسانه ها را به خود اختصاص نداده ایم ، بنابراین شما هنوز نمی توانید در دستگاه بازیگران فیلم پخش کنید. برای قطع ارتباط بر روی دکمه CAST کلیک کنید.

6. ریخته گری محتوای ویدیویی

تصویر یک تلفن اندرویدی که برنامه "فیلم های بازیگران" را اجرا می کند

ما برنامه نمونه را گسترش خواهیم داد تا فیلم ها را از راه دور بر روی دستگاه بازیگران پخش کنیم. برای انجام این کار ، ما باید به رویدادهای مختلف ایجاد شده توسط چارچوب بازیگران گوش دهیم.

رسانه های ریخته گری

در سطح بالایی ، اگر می خواهید رسانه ای را در دستگاه بازیگران بازی کنید ، باید این کارها را انجام دهید:

  1. یک شیء MediaInfo ایجاد کنید که یک مورد رسانه ای را مدل کند.
  2. به دستگاه ریخته گری متصل شوید و برنامه گیرنده خود را راه اندازی کنید.
  3. شیء MediaInfo را در گیرنده خود بارگیری کرده و محتوا را بازی کنید.
  4. وضعیت رسانه را پیگیری کنید.
  5. ارسال دستورات پخش به گیرنده بر اساس تعامل کاربر.

ما قبلاً مرحله 2 را در بخش قبلی انجام داده ایم. مرحله 3 با چارچوب بازیگران آسان است. مرحله 1 برای نقشه برداری یک شی به شیء دیگر است. MediaInfo چیزی است که چارچوب بازیگران آن را درک می کند و MediaItem محاصره برنامه ما برای یک مورد رسانه ای است. ما به راحتی می توانیم یک MediaItem را به یک MediaInfo ترسیم کنیم.

برنامه نمونه LocalPlayerActivity در حال حاضر بین پخش محلی در مقابل از راه دور با استفاده از این enum تمایز قائل می شود:

private var mLocation: PlaybackLocation? = null

enum class PlaybackLocation {
    LOCAL, REMOTE
}

enum class PlaybackState {
    PLAYING, PAUSED, BUFFERING, IDLE
}

در این CodeLab برای شما مهم نیست که دقیقاً درک کنید که تمام منطق نمونه پخش کننده نمونه کار می کند. درک این نکته مهم است که پخش کننده رسانه برنامه شما باید اصلاح شود تا از دو مکان پخش به روشی مشابه آگاه باشد.

در حال حاضر بازیکن محلی همیشه در حالت پخش محلی قرار دارد زیرا هنوز چیزی در مورد حالت های ریخته گری نمی داند. ما باید UI را بر اساس انتقال حالت که در چارچوب بازیگران اتفاق می افتد ، به روز کنیم. به عنوان مثال ، اگر شروع به بازیگری کنیم ، باید جلوی پخش محلی را بگیریم و برخی از کنترل ها را غیرفعال کنیم. به همین ترتیب ، اگر وقتی در این فعالیت هستیم ، از ریخته گری متوقف شویم ، باید به پخش محلی منتقل شویم. برای رسیدگی به این امر باید به رویدادهای مختلفی که توسط چارچوب بازیگران ایجاد شده است گوش دهیم.

مدیریت جلسه بازیگران

برای چارچوب بازیگران یک جلسه بازیگران مراحل اتصال به یک دستگاه ، راه اندازی (یا پیوستن) ، اتصال به یک برنامه گیرنده و در صورت لزوم کانال کنترل رسانه را ترکیب می کند. کانال کنترل رسانه ای است که چگونه چارچوب بازیگران پیام های بازیکن گیرنده رسانه را ارسال و دریافت می کند.

هنگامی که کاربر دستگاهی را از دکمه CAST انتخاب می کند ، جلسه بازیگران به صورت خودکار شروع می شود و در هنگام قطع کاربر به طور خودکار متوقف می شود. اتصال مجدد به جلسه گیرنده به دلیل مشکلات شبکه نیز به طور خودکار توسط بازیگران SDK انجام می شود.

بیایید یک SessionManagerListener را به LocalPlayerActivity اضافه کنیم:

import com.google.android.gms.cast.framework.CastSession
import com.google.android.gms.cast.framework.SessionManagerListener
...

private var mSessionManagerListener: SessionManagerListener<CastSession>? = null
private var mCastSession: CastSession? = null
...

private fun setupCastListener() {
    mSessionManagerListener = object : SessionManagerListener<CastSession> {
        override fun onSessionEnded(session: CastSession, error: Int) {
            onApplicationDisconnected()
        }

        override fun onSessionResumed(session: CastSession, wasSuspended: Boolean) {
            onApplicationConnected(session)
        }

        override fun onSessionResumeFailed(session: CastSession, error: Int) {
            onApplicationDisconnected()
        }

        override fun onSessionStarted(session: CastSession, sessionId: String) {
            onApplicationConnected(session)
        }

        override fun onSessionStartFailed(session: CastSession, error: Int) {
            onApplicationDisconnected()
        }

        override fun onSessionStarting(session: CastSession) {}
        override fun onSessionEnding(session: CastSession) {}
        override fun onSessionResuming(session: CastSession, sessionId: String) {}
        override fun onSessionSuspended(session: CastSession, reason: Int) {}
        private fun onApplicationConnected(castSession: CastSession) {
            mCastSession = castSession
            if (null != mSelectedMedia) {
                if (mPlaybackState == PlaybackState.PLAYING) {
                    mVideoView!!.pause()
                    loadRemoteMedia(mSeekbar!!.progress, true)
                    return
                } else {
                    mPlaybackState = PlaybackState.IDLE
                    updatePlaybackLocation(PlaybackLocation.REMOTE)
                }
            }
            updatePlayButton(mPlaybackState)
            invalidateOptionsMenu()
        }

        private fun onApplicationDisconnected() {
            updatePlaybackLocation(PlaybackLocation.LOCAL)
            mPlaybackState = PlaybackState.IDLE
            mLocation = PlaybackLocation.LOCAL
            updatePlayButton(mPlaybackState)
            invalidateOptionsMenu()
       }
   }
}

در فعالیت LocalPlayerActivity ، ما علاقه مندیم که هنگام اتصال یا قطع شدن از دستگاه ریخته گری ، مطلع شویم تا بتوانیم به بازیکن محلی یا از آن تغییر دهیم. توجه داشته باشید که اتصال نه تنها با استفاده از برنامه کاربردی شما که در دستگاه تلفن همراه شما اجرا می شود ، می تواند مختل شود ، بلکه می تواند با نمونه دیگری از برنامه (یا دیگری) شما که روی یک دستگاه تلفن همراه متفاوت اجرا می شود ، مختل شود.

جلسه فعال در حال حاضر به عنوان SessionManager.getCurrentSession() قابل دسترسی است. جلسات در پاسخ به تعامل کاربر با گفتگوی های بازیگران به طور خودکار ایجاد و پاره می شوند.

ما باید شنونده جلسه خود را ثبت کنیم و برخی از متغیرهایی را که در فعالیت استفاده خواهیم کرد ، آغاز کنیم. روش onCreate LocalPlayerActivity را به:

import com.google.android.gms.cast.framework.CastContext
...

private var mCastContext: CastContext? = null
...

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    mCastContext = CastContext.getSharedInstance(this)
    mCastSession = mCastContext!!.sessionManager.currentCastSession
    setupCastListener()
    ...
    loadViews()
    ...
    val bundle = intent.extras
    if (bundle != null) {
        ....
        if (shouldStartPlayback) {
              ....

        } else {
            if (mCastSession != null && mCastSession!!.isConnected()) {
                updatePlaybackLocation(PlaybackLocation.REMOTE)
            } else {
                updatePlaybackLocation(PlaybackLocation.LOCAL)
            }
            mPlaybackState = PlaybackState.IDLE
            updatePlayButton(mPlaybackState)
        }
    }
    ...
}

در حال بارگیری رسانه

در بازیگران SDK ، RemoteMediaClient مجموعه ای از API های مناسب را برای مدیریت پخش رسانه ای از راه دور روی گیرنده فراهم می کند. برای یک CastSession که از پخش رسانه پشتیبانی می کند ، نمونه ای از RemoteMediaClient به طور خودکار توسط SDK ایجاد می شود. با فراخوانی روش getRemoteMediaClient() در نمونه CastSession می توان به آن دسترسی پیدا کرد. روش های زیر را به LocalPlayerActivity اضافه کنید تا فیلم انتخاب شده در حال حاضر روی گیرنده بارگذاری شود:

import com.google.android.gms.cast.framework.media.RemoteMediaClient
import com.google.android.gms.cast.MediaInfo
import com.google.android.gms.cast.MediaLoadOptions
import com.google.android.gms.cast.MediaMetadata
import com.google.android.gms.common.images.WebImage
import com.google.android.gms.cast.MediaLoadRequestData

private fun loadRemoteMedia(position: Int, autoPlay: Boolean) {
    if (mCastSession == null) {
        return
    }
    val remoteMediaClient = mCastSession!!.remoteMediaClient ?: return
    remoteMediaClient.load( MediaLoadRequestData.Builder()
                .setMediaInfo(buildMediaInfo())
                .setAutoplay(autoPlay)
                .setCurrentTime(position.toLong()).build())
}

private fun buildMediaInfo(): MediaInfo? {
    val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE)
    mSelectedMedia?.studio?.let { movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, it) }
    mSelectedMedia?.title?.let { movieMetadata.putString(MediaMetadata.KEY_TITLE, it) }
    movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia!!.getImage(0))))
    movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia!!.getImage(1))))
    return mSelectedMedia!!.url?.let {
        MediaInfo.Builder(it)
            .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
            .setContentType("videos/mp4")
            .setMetadata(movieMetadata)
            .setStreamDuration((mSelectedMedia!!.duration * 1000).toLong())
            .build()
    }
}

اکنون روشهای مختلف موجود را برای استفاده از منطق جلسه CAST برای پشتیبانی از پخش از راه دور به روز کنید:

private fun play(position: Int) {
    startControllersTimer()
    when (mLocation) {
        PlaybackLocation.LOCAL -> {
            mVideoView!!.seekTo(position)
            mVideoView!!.start()
        }
        PlaybackLocation.REMOTE -> {
            mPlaybackState = PlaybackState.BUFFERING
            updatePlayButton(mPlaybackState)
            //seek to a new position within the current media item's new position 
            //which is in milliseconds from the beginning of the stream
            mCastSession!!.remoteMediaClient?.seek(position.toLong())
        }
        else -> {}
    }
    restartTrickplayTimer()
}
private fun togglePlayback() {
    ...
    PlaybackState.IDLE -> when (mLocation) {
        ...
        PlaybackLocation.REMOTE -> {
            if (mCastSession != null && mCastSession!!.isConnected) {
                loadRemoteMedia(mSeekbar!!.progress, true)
            }
        }
        else -> {}
    }
    ...
}
override fun onPause() {
    ...
    mCastContext!!.sessionManager.removeSessionManagerListener(
                mSessionManagerListener!!, CastSession::class.java)
}
override fun onResume() {
    Log.d(TAG, "onResume() was called")
    mCastContext!!.sessionManager.addSessionManagerListener(
            mSessionManagerListener!!, CastSession::class.java)
    if (mCastSession != null && mCastSession!!.isConnected) {
        updatePlaybackLocation(PlaybackLocation.REMOTE)
    } else {
        updatePlaybackLocation(PlaybackLocation.LOCAL)
    }
    super.onResume()
}

برای روش updatePlayButton ، مقدار متغیر isConnected را تغییر دهید:

private fun updatePlayButton(state: PlaybackState?) {
    ...
    val isConnected = (mCastSession != null
                && (mCastSession!!.isConnected || mCastSession!!.isConnecting))
    ...
}

اکنون ، روی کلیک کنید دکمه اجرا Android Studio ، یک مثلث سبز که به سمت راست نشان می دهد دکمه را اجرا کنید تا برنامه را روی دستگاه تلفن همراه خود اجرا کنید. به دستگاه بازیگران خود وصل شوید و پخش یک فیلم را شروع کنید. شما باید فیلم را روی گیرنده پخش کنید.

7. مینی کنترل کننده

چک لیست طراحی بازیگران نیاز دارد که تمام برنامه های بازیگران یک کنترلر مینی ارائه دهند که هنگام حرکت کاربر از صفحه محتوای فعلی ظاهر می شود. Mini Controller دسترسی فوری و یادآوری قابل مشاهده برای جلسه بازیگران فعلی را فراهم می کند.

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

Cast SDK نمای سفارشی ، MiniControllerFragment را ارائه می دهد ، که می تواند به پرونده طرح برنامه از فعالیتهایی که می خواهید مینی کنترلر را نشان دهید اضافه شود.

تعریف قطعه زیر را به پایین هر دو res/layout/player_activity.xml و res/layout/video_browser.xml اضافه کنید:

<fragment
    android:id="@+id/castMiniController"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:visibility="gone"
    class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment"/>

کلیک بر روی دکمه اجرا Android Studio ، یک مثلث سبز که به سمت راست نشان می دهد دکمه را اجرا کنید تا برنامه را اجرا کنید و یک ویدیو بازی کنید. هنگامی که پخش روی گیرنده شروع می شود ، باید مشاهده کنید که Mini Controller در پایین هر فعالیت ظاهر می شود. می توانید پخش از راه دور را با استفاده از Mini Controller کنترل کنید. اگر بین فعالیت مرور و فعالیت پخش کننده محلی حرکت کنید ، وضعیت Mini Controller باید با وضعیت پخش رسانه گیرنده همگام بماند.

8. صفحه اعلان و قفل

چک لیست طراحی Google Cast برای اجرای کنترل رسانه ها از یک اعلان و صفحه قفل به یک برنامه فرستنده نیاز دارد.

تصویر یک تلفن اندرویدی که کنترل رسانه ها را در منطقه اعلان ها نشان می دهد

Cast SDK برای کمک به برنامه فرستنده برای ایجاد کنترل رسانه برای صفحه اعلان و قفل ، یک MediaNotificationService ارائه می دهد. این سرویس به طور خودکار توسط Gradle در مانیفست برنامه شما ادغام می شود.

MediaNotificationService در هنگام ریخته گری فرستنده در پس زمینه اجرا می شود و با یک تصویر کوچک تصویر و ابرداده در مورد مورد ریخته گری فعلی ، یک دکمه پخش/مکث و یک دکمه توقف ، اعلان را نشان می دهد.

کنترل های صفحه نمایش اعلان و قفل را می توان با استفاده از CastOptions هنگام اولیه سازی CastContext فعال کرد. کنترل رسانه برای صفحه اعلان و قفل به طور پیش فرض روشن می شود. ویژگی صفحه قفل تا زمانی که اعلان روشن شود روشن می شود.

CastOptionsProvider را ویرایش کرده و اجرای getCastOptions را برای مطابقت با این کد تغییر دهید:

import com.google.android.gms.cast.framework.media.CastMediaOptions
import com.google.android.gms.cast.framework.media.NotificationOptions

override fun getCastOptions(context: Context): CastOptions {
   val notificationOptions = NotificationOptions.Builder()
            .setTargetActivityClassName(VideoBrowserActivity::class.java.name)
            .build()
    val mediaOptions = CastMediaOptions.Builder()
            .setNotificationOptions(notificationOptions)
            .build()
   return CastOptions.Builder()
                .setReceiverApplicationId(context.getString(R.string.app_id))
                .setCastMediaOptions(mediaOptions)
                .build()
}

کلیک بر روی دکمه اجرا Android Studio ، یک مثلث سبز که به سمت راست نشان می دهد دکمه را اجرا کنید تا برنامه را روی دستگاه تلفن همراه خود اجرا کنید. یک ویدیو ریخته و از برنامه نمونه دور شوید. باید برای این ویدئویی که در حال حاضر در گیرنده پخش می شود ، اعلان وجود داشته باشد. دستگاه تلفن همراه خود را قفل کنید و صفحه قفل اکنون باید کنترل های پخش رسانه را در دستگاه بازیگران نشان دهد.

تصویر یک تلفن اندرویدی که کنترل رسانه ها را در صفحه قفل نشان می دهد

9. روکش مقدماتی

چک لیست طراحی Google Cast به یک برنامه فرستنده نیاز دارد تا دکمه بازیگران را به کاربران موجود معرفی کند تا به آنها اطلاع دهد که برنامه فرستنده اکنون از ریخته گری پشتیبانی می کند و همچنین به کاربران جدید در Google Cast کمک می کند.

تصویر نشان دادن پوشش بازیگران مقدماتی در اطراف دکمه بازیگران در برنامه Android Cast Video

Cast SDK نمای سفارشی ، IntroductoryOverlay ارائه می دهد ، که می تواند برای برجسته کردن دکمه بازیگران در هنگام اولین بار به کاربران استفاده شود. کد زیر را به VideoBrowserActivity اضافه کنید:

import com.google.android.gms.cast.framework.IntroductoryOverlay
import android.os.Looper

private var mIntroductoryOverlay: IntroductoryOverlay? = null

private fun showIntroductoryOverlay() {
    mIntroductoryOverlay?.remove()
    if (mediaRouteMenuItem?.isVisible == true) {
       Looper.myLooper().run {
           mIntroductoryOverlay = com.google.android.gms.cast.framework.IntroductoryOverlay.Builder(
                    this@VideoBrowserActivity, mediaRouteMenuItem!!)
                   .setTitleText("Introducing Cast")
                   .setSingleTime()
                   .setOnOverlayDismissedListener(
                           object : IntroductoryOverlay.OnOverlayDismissedListener {
                               override fun onOverlayDismissed() {
                                   mIntroductoryOverlay = null
                               }
                          })
                   .build()
          mIntroductoryOverlay!!.show()
        }
    }
}

اکنون ، یک CastStateListener اضافه کنید و وقتی یک دستگاه ریخته گری با اصلاح روش onCreate در دسترس است و روش های onResume و onPause را نادیده بگیرید ، با روش showIntroductoryOverlay تماس بگیرید:

import com.google.android.gms.cast.framework.CastState
import com.google.android.gms.cast.framework.CastStateListener

private var mCastStateListener: CastStateListener? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.video_browser)
    setupActionBar()
    mCastStateListener = object : CastStateListener {
            override fun onCastStateChanged(newState: Int) {
                if (newState != CastState.NO_DEVICES_AVAILABLE) {
                    showIntroductoryOverlay()
                }
            }
        }
    mCastContext = CastContext.getSharedInstance(this)
}

override fun onResume() {
    super.onResume()
    mCastContext?.addCastStateListener(mCastStateListener!!)
}

override fun onPause() {
    super.onPause()
    mCastContext?.removeCastStateListener(mCastStateListener!!)
}

داده های برنامه را پاک کنید یا برنامه را از دستگاه خود حذف کنید. سپس ، روی کلیک کنید دکمه اجرا Android Studio ، یک مثلث سبز که به سمت راست نشان می دهد دکمه را اجرا کنید تا برنامه را روی دستگاه تلفن همراه خود اجرا کنید و باید پوشش مقدماتی را مشاهده کنید (اگر پوشش داده نشود ، داده های برنامه را پاک کنید).

10. کنترلر گسترش یافته

چک لیست طراحی Google Cast به یک برنامه فرستنده نیاز دارد تا کنترلر گسترده ای را برای رسانه های بازیگران ارائه دهد. کنترلر گسترش یافته یک نسخه کامل از Mini Controller است.

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

بازیگران SDK ویجت را برای کنترلر گسترش یافته به نام ExpandedControllerActivity فراهم می کند. این یک کلاس انتزاعی است که شما باید برای اضافه کردن یک دکمه بازیگران ، زیر کلاس داشته باشید.

در مرحله اول ، یک فایل منبع منو جدید به نام expanded_controller.xml ایجاد کنید تا کنترلر گسترش یافته دکمه CAST را فراهم کند:

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
            android:id="@+id/media_route_menu_item"
            android:title="@string/media_route_menu_title"
            app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
            app:showAsAction="always"/>

</menu>

یک بسته جدید expandedcontrols در بسته com.google.sample.cast.refplayer ایجاد کنید. در مرحله بعد ، یک فایل جدید به نام ExpandedControlsActivity.kt در بسته com.google.sample.cast.refplayer.expandedcontrols ایجاد کنید.

package com.google.sample.cast.refplayer.expandedcontrols

import android.view.Menu
import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity
import com.google.sample.cast.refplayer.R
import com.google.android.gms.cast.framework.CastButtonFactory

class ExpandedControlsActivity : ExpandedControllerActivity() {
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        super.onCreateOptionsMenu(menu)
        menuInflater.inflate(R.menu.expanded_controller, menu)
        CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item)
        return true
    }
}

اکنون در برچسب application بالاتر از OPTIONS_PROVIDER_CLASS_NAME ExpandedControlsActivity در AndroidManifest.xml اعلام کنید:

<application>
    ...
    <activity
        android:name="com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity"
        android:label="@string/app_name"
        android:launchMode="singleTask"
        android:theme="@style/Theme.CastVideosDark"
        android:screenOrientation="portrait"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
        </intent-filter>
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.google.sample.cast.refplayer.VideoBrowserActivity"/>
    </activity>
    ...
</application>

برای تنظیم فعالیت هدف به فعالیت ExpandedControlsActivity ویرایش CastOptionsProvider و تغییر NotificationOptions و CastMediaOptions :

import com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity

override fun getCastOptions(context: Context): CastOptions {
    val notificationOptions = NotificationOptions.Builder()
            .setTargetActivityClassName(ExpandedControlsActivity::class.java.name)
            .build()
    val mediaOptions = CastMediaOptions.Builder()
            .setNotificationOptions(notificationOptions)
            .setExpandedControllerActivityClassName(ExpandedControlsActivity::class.java.name)
            .build()
    return CastOptions.Builder()
            .setReceiverApplicationId(context.getString(R.string.app_id))
            .setCastMediaOptions(mediaOptions)
            .build()
}

روش LocalPlayerActivity loadRemoteMedia به روز کنید تا در هنگام بارگیری رسانه از راه دور ، ExpandedControlsActivity نمایش دهید:

import com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity

private fun loadRemoteMedia(position: Int, autoPlay: Boolean) {
    if (mCastSession == null) {
        return
    }
    val remoteMediaClient = mCastSession!!.remoteMediaClient ?: return
    remoteMediaClient.registerCallback(object : RemoteMediaClient.Callback() {
        override fun onStatusUpdated() {
            val intent = Intent(this@LocalPlayerActivity, ExpandedControlsActivity::class.java)
            startActivity(intent)
            remoteMediaClient.unregisterCallback(this)
        }
    })
    remoteMediaClient.load(MediaLoadRequestData.Builder()
                .setMediaInfo(buildMediaInfo())
                .setAutoplay(autoPlay)
                .setCurrentTime(position.toLong()).build())
}

کلیک بر روی دکمه اجرا Android Studio ، یک مثلث سبز که به سمت راست نشان می دهد دکمه را اجرا کنید تا برنامه را روی دستگاه تلفن همراه خود اجرا کنید و یک ویدیو بازی کنید. شما باید کنترلر گسترش یافته را ببینید. دوباره به لیست فیلم ها بروید و هنگامی که روی Mini Controller کلیک می کنید ، کنترلر گسترش یافته دوباره بارگیری می شود. برای دیدن اعلان به دور از برنامه حرکت کنید. برای بارگیری کنترلر گسترش یافته روی تصویر اعلان کلیک کنید.

11. پشتیبانی COST Connect را اضافه کنید

کتابخانه Cast Connect به برنامه های ارسال کننده موجود اجازه می دهد تا از طریق پروتکل بازیگران با برنامه های تلویزیونی Android ارتباط برقرار کنند. Cast Connect در بالای زیرساخت های بازیگران ساخته شده است و برنامه تلویزیون Android شما به عنوان گیرنده عمل می کند.

وابستگی ها

توجه: برای اجرای CAST CONNECT ، play-services-cast-framework باید 19.0.0 یا بالاتر باشد.

راه اندازی

برای راه اندازی برنامه Android TV ، همچنین به عنوان گیرنده Android نیز گفته می شود ، ما باید پرچم سازگار setAndroidReceiverCompatible را در شیء LaunchOptions تنظیم کنیم. این شیء LaunchOptions نحوه راه اندازی گیرنده را نشان می دهد و به CastOptions برگردانده شده توسط کلاس CastOptionsProvider منتقل می شود. تنظیم پرچم ذکر شده در false ، گیرنده وب را برای شناسه برنامه تعریف شده در کنسول توسعه دهنده بازیگران راه اندازی می کند.

در پرونده CastOptionsProvider.kt موارد زیر را به روش getCastOptions اضافه کنید:

import com.google.android.gms.cast.LaunchOptions
...
val launchOptions = LaunchOptions.Builder()
            .setAndroidReceiverCompatible(true)
            .build()
return new CastOptions.Builder()
        .setLaunchOptions(launchOptions)
        ...
        .build()

اعتبار راه اندازی را تنظیم کنید

از طرف فرستنده ، می توانید CredentialsData مشخص کنید تا نماینده چه کسی در جلسه باشد. credentials رشته ای است که می تواند تعریف شده توسط کاربر باشد ، تا زمانی که برنامه ATV شما بتواند آن را درک کند. CredentialsData فقط در هنگام راه اندازی یا پیوستن به برنامه Android TV شما منتقل می شود. اگر دوباره آن را تنظیم کنید در حالی که متصل هستید ، به برنامه تلویزیون Android شما منتقل نمی شود.

به منظور تنظیم اعتبارنامه های راه اندازی ، باید CredentialsData تعریف شود و به شیء LaunchOptions منتقل شود. کد زیر را به روش getCastOptions در پرونده CastOptionsProvider.kt خود اضافه کنید:

import com.google.android.gms.cast.CredentialsData
...

val credentialsData = CredentialsData.Builder()
        .setCredentials("{\"userId\": \"abc\"}")
        .build()
val launchOptions = LaunchOptions.Builder()
       ...
       .setCredentialsData(credentialsData)
       .build()

اعتبار را در LoadRequest تنظیم کنید

در صورتی که برنامه گیرنده وب و برنامه های Android TV شما به طور متفاوتی از credentials استفاده کند ، ممکن است لازم باشد credentials جداگانه ای را برای هر یک تعریف کنید. برای مراقبت از آن ، کد زیر را در پرونده LocalPlayerActivity.kt خود در زیر عملکرد loadRemoteMedia اضافه کنید:

remoteMediaClient.load(MediaLoadRequestData.Builder()
       ...
       .setCredentials("user-credentials")
       .setAtvCredentials("atv-user-credentials")
       .build())

بسته به برنامه گیرنده فرستنده شما در حال ریخته گری است ، SDK اکنون به طور خودکار از کدام اعتبار برای جلسه فعلی استفاده می کند.

تست بازیگران اتصال

مراحل نصب Android TV APK در Chromecast با Google TV

  1. آدرس IP دستگاه تلویزیون Android خود را پیدا کنید. معمولاً تحت تنظیمات> شبکه و اینترنت> (نام شبکه ای که دستگاه شما به آن متصل است) در دسترس است. از طرف راست ، جزئیات و IP دستگاه شما را در شبکه نشان می دهد.
  2. از آدرس IP برای دستگاه خود استفاده کنید تا از طریق ADB با استفاده از ترمینال به آن وصل شوید:
$ adb connect <device_ip_address>:5555
  1. از پنجره ترمینال خود ، برای نمونه های CodeLab که در ابتدای این CodeLab بارگیری کرده اید ، به پوشه سطح بالا بروید. به عنوان مثال:
$ cd Desktop/android_codelab_src
  1. فایل .apk را در این پوشه در تلویزیون اندرویدی خود نصب کنید:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. اکنون باید بتوانید برنامه ای را با نام فیلم های بازیگران در منوی برنامه های خود در دستگاه تلویزیون Android خود مشاهده کنید.
  2. به پروژه Android Studio خود برگردید و بر روی دکمه Run کلیک کنید تا برنامه Sender را در دستگاه تلفن همراه فیزیکی خود نصب و اجرا کنید. در گوشه سمت راست سمت راست ، روی نماد بازیگران کلیک کنید و دستگاه Android TV خود را از گزینه های موجود انتخاب کنید. اکنون باید برنامه Android TV را که در دستگاه Android TV خود راه اندازی شده است ، مشاهده کنید و در حال پخش یک ویدیو باید به شما امکان دهد با استفاده از Remote Android TV خود ، پخش ویدیویی را کنترل کنید.

12. ابزارک های بازیگران را سفارشی کنید

شما می توانید ابزارک های بازیگران را با تنظیم رنگ ها ، یک ظاهر طراحی دکمه ها ، متن و ظاهر کوچک و با انتخاب انواع دکمه ها برای نمایش ، سفارشی کنید.

به روزرسانی res/values/styles_castvideo.xml

<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
    ...
    <item name="mediaRouteTheme">@style/CustomMediaRouterTheme</item>
    <item name="castIntroOverlayStyle">@style/CustomCastIntroOverlay</item>
    <item name="castMiniControllerStyle">@style/CustomCastMiniController</item>
    <item name="castExpandedControllerStyle">@style/CustomCastExpandedController</item>
    <item name="castExpandedControllerToolbarStyle">
        @style/ThemeOverlay.AppCompat.ActionBar
    </item>
    ...
</style>

مضامین سفارشی زیر را اعلام کنید:

<!-- Customize Cast Button -->
<style name="CustomMediaRouterTheme" parent="Theme.MediaRouter">
    <item name="mediaRouteButtonStyle">@style/CustomMediaRouteButtonStyle</item>
</style>
<style name="CustomMediaRouteButtonStyle" parent="Widget.MediaRouter.Light.MediaRouteButton">
    <item name="mediaRouteButtonTint">#EEFF41</item>
</style>

<!-- Customize Introductory Overlay -->
<style name="CustomCastIntroOverlay" parent="CastIntroOverlay">
    <item name="castButtonTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Button</item>
    <item name="castTitleTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Title</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Button" parent="android:style/TextAppearance">
    <item name="android:textColor">#FFFFFF</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Title" parent="android:style/TextAppearance.Large">
    <item name="android:textColor">#FFFFFF</item>
</style>

<!-- Customize Mini Controller -->
<style name="CustomCastMiniController" parent="CastMiniController">
    <item name="castShowImageThumbnail">true</item>
    <item name="castTitleTextAppearance">@style/TextAppearance.AppCompat.Subhead</item>
    <item name="castSubtitleTextAppearance">@style/TextAppearance.AppCompat.Caption</item>
    <item name="castBackground">@color/accent</item>
    <item name="castProgressBarColor">@color/orange</item>
</style>

<!-- Customize Expanded Controller -->
<style name="CustomCastExpandedController" parent="CastExpandedController">
    <item name="castButtonColor">#FFFFFF</item>
    <item name="castPlayButtonDrawable">@drawable/cast_ic_expanded_controller_play</item>
    <item name="castPauseButtonDrawable">@drawable/cast_ic_expanded_controller_pause</item>
    <item name="castStopButtonDrawable">@drawable/cast_ic_expanded_controller_stop</item>
</style>

13. تبریک می گویم

شما اکنون می دانید که چگونه یک برنامه ویدیویی را با استفاده از ابزارک های SDK Cast در Android قابل چاپ قرار دهید.

برای اطلاعات بیشتر ، به راهنمای توسعه دهنده Android Sender مراجعه کنید.