«تعویضکننده برونداد» یکی از ویژگیهای «کیت توسعه نرمافزار پخش محتوا» است که انتقال یکپارچه بین بازپخش محلی و از دور محتوا را از Android 13 امکانپذیر میکند. هدف این است که به برنامههای فرستنده کمک کند بهراحتی و بهسرعت کنترل کنند محتوا کجا پخش میشود.
«تعویضکننده خروجی» از کتابخانه
MediaRouter برای
جابهجایی بازپخش محتوا بین بلندگوی تلفن، دستگاههای بلوتوث جفتشده،
و دستگاههای دور سازگار با Cast استفاده میکند. موارد استفاده را میتوان به سناریوهای زیر تقسیم کرد:
برای اطلاع از نحوه پیادهسازی «تعویضکننده برونداد» در برنامهتان، برنامه نمونه CastVideos-android را بارگیری و استفاده کنید.
«تعویضکننده برونداد» باید فعال شود تا از محلی به راه دور، از راه دور به محلی، و از راه دور به راه دور بااستفاده از مراحل پوششدادهشده در این راهنما پشتیبانی کند. برای پشتیبانی از انتقال بین بلندگوهای دستگاه محلی و دستگاههای بلوتوث جفتشده، به مراحل اضافی نیاز نیست.
رابط کاربری «تعویضکننده خروجی»
«تعویضکننده خروجی» دستگاههای محلی و راه دور دردسترس را و همچنین وضعیت فعلی دستگاهها را نمایش میدهد، ازجمله اینکه دستگاه انتخاب شده است یا نه، درحال اتصال است یا نه، و سطح صدای فعلی. اگر علاوهبر دستگاه فعلی دستگاههای دیگری وجود داشته باشد، با کلیک کردن روی دستگاه دیگر میتوانید بازپخش رسانه را به دستگاه انتخابشده منتقل کنید.

مشکلات شناختهشده
- «جلسههای رسانه» ایجادشده برای بازپخش محلی هنگام جابهجایی به اعلان Cast SDK بسته و دوباره ایجاد خواهد شد.
نقطههای ورودی
اعلان رسانه
اگر برنامهای اعلان رسانهای با
MediaSession برای
بازپخش محلی (پخش محلی) پست کند، گوشه بالای اعلان رسانه
تراشه اعلانی با نام دستگاهی (مثل بلندگوی تلفن) که
محتوا درحالحاضر در آن پخش میشود نمایش میدهد. با تکضرب زدن روی تراشه اعلان،
واسط کاربر سیستم کادر گفتگوی «تعویضکننده برونداد» باز میشود.

تنظیمات میزان صدا
واسط کاربر سیستم گفتگوی «تعویضکننده برونداد» را میتوان با کلیک کردن روی دکمههای فیزیکی میزان صدا در دستگاه، تکضرب زدن روی نماد تنظیمات در پایین، و تکضرب زدن روی نوشتار «پخش <نام برنامه> در <دستگاه پخش محتوا>» نیز راهاندازی کرد.

خلاصه مراحل
- مطمئن شوید پیشنیازها برآورده شده است
- فعال کردن «تعویضکننده خروجی» در AndroidManifest.xml
- بهروزرسانی SessionManagerListener برای ارسال محتوا در پسزمینه
- افزودن پشتیبانی برای «ازراهدور به ازراهدور»
- تنظیم پرچم setRemoteToLocalEnabled
- ادامه بازپخش بهصورت محلی
پیشنیازها
- برنامه Android موجودتان را به AndroidX منتقل کنید.
build.gradleبرنامهتان را بهروز کنید تا از حداقل نسخه لازم «کیت توسعه نرمافزار فرستنده Android» برای «تعویضکننده خروجی» استفاده کند:dependencies { ... implementation 'com.google.android.gms:play-services-cast-framework:21.2.0' ... }
- برنامه از اعلانهای رسانه پشتیبانی میکند.
- دستگاه دارای Android 13.
راهاندازی اعلانهای رسانه
برای استفاده از «تعویضکننده خروجی»،
برنامههای صوتی و
ویدیویی
باید اعلان رسانهای ایجاد کنند تا وضعیت بازپخش و
کنترلهای رسانه برای بازپخش محلی نمایش داده شود. برای این کار باید
MediaSession ایجاد کنید،
MediaStyle را با کد MediaSession تنظیم کنید، و کنترلهای رسانه را در اعلان تنظیم کنید.
اگر درحالحاضر از MediaStyle و MediaSession استفاده نمیکنید،
گزیده زیر نحوه راهاندازی آنها را نشان میدهد و راهنماهایی برای راهاندازی
بازخوانهای جلسه رسانه برای
صدا و
ویدیو
برنامهها دردسترس است:
// Create a media session. NotificationCompat.MediaStyle // PlayerService is your own Service or Activity responsible for media playback. val mediaSession = MediaSessionCompat(this, "PlayerService") // Create a MediaStyle object and supply your media session token to it. val mediaStyle = Notification.MediaStyle().setMediaSession(mediaSession.sessionToken) // Create a Notification which is styled by your MediaStyle object. // This connects your media session to the media controls. // Don't forget to include a small icon. val notification = Notification.Builder(this@PlayerService, CHANNEL_ID) .setStyle(mediaStyle) .setSmallIcon(R.drawable.ic_app_logo) .build() // Specify any actions which your users can perform, such as pausing and skipping to the next track. val pauseAction: Notification.Action = Notification.Action.Builder( pauseIcon, "Pause", pauseIntent ).build() notification.addAction(pauseAction)
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { // Create a media session. NotificationCompat.MediaStyle // PlayerService is your own Service or Activity responsible for media playback. MediaSession mediaSession = new MediaSession(this, "PlayerService"); // Create a MediaStyle object and supply your media session token to it. Notification.MediaStyle mediaStyle = new Notification.MediaStyle().setMediaSession(mediaSession.getSessionToken()); // Specify any actions which your users can perform, such as pausing and skipping to the next track. Notification.Action pauseAction = Notification.Action.Builder(pauseIcon, "Pause", pauseIntent).build(); // Create a Notification which is styled by your MediaStyle object. // This connects your media session to the media controls. // Don't forget to include a small icon. String CHANNEL_ID = "CHANNEL_ID"; Notification notification = new Notification.Builder(this, CHANNEL_ID) .setStyle(mediaStyle) .setSmallIcon(R.drawable.ic_app_logo) .addAction(pauseAction) .build(); }

علاوهبراین، برای پر کردن اعلان با اطلاعات رسانهتان،
باید
فراداده و وضعیت بازپخش
رسانهتان را به MediaSession اضافه کنید.
برای افزودن فراداده به MediaSession، از
setMetaData()
استفاده کنید و همه ثابتهای
MediaMetadata مربوط به رسانهتان را در
MediaMetadataCompat.Builder() ارائه دهید.
mediaSession.setMetadata(MediaMetadataCompat.Builder() // Title .putString(MediaMetadata.METADATA_KEY_TITLE, currentTrack.title) // Artist // Could also be the channel name or TV series. .putString(MediaMetadata.METADATA_KEY_ARTIST, currentTrack.artist) // Album art // Could also be a screenshot or hero image for video content // The URI scheme needs to be "content", "file", or "android.resource". .putString( MediaMetadata.METADATA_KEY_ALBUM_ART_URI, currentTrack.albumArtUri) ) // Duration // If duration isn't set, such as for live broadcasts, then the progress // indicator won't be shown on the seekbar. .putLong(MediaMetadata.METADATA_KEY_DURATION, currentTrack.duration) .build() )
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { mediaSession.setMetadata( new MediaMetadataCompat.Builder() // Title .putString(MediaMetadata.METADATA_KEY_TITLE, currentTrack.title) // Artist // Could also be the channel name or TV series. .putString(MediaMetadata.METADATA_KEY_ARTIST, currentTrack.artist) // Album art // Could also be a screenshot or hero image for video content // The URI scheme needs to be "content", "file", or "android.resource". .putString(MediaMetadata.METADATA_KEY_ALBUM_ART_URI, currentTrack.albumArtUri) // Duration // If duration isn't set, such as for live broadcasts, then the progress // indicator won't be shown on the seekbar. .putLong(MediaMetadata.METADATA_KEY_DURATION, currentTrack.duration) .build() ); }

برای افزودن وضعیت بازپخش به MediaSession، از
setPlaybackState()
استفاده کنید و همه ثابتهای
PlaybackStateCompat
مربوط به رسانهتان را در
PlaybackStateCompat.Builder() ارائه دهید.
mediaSession.setPlaybackState( PlaybackStateCompat.Builder() .setState( PlaybackStateCompat.STATE_PLAYING, // Playback position // Used to update the elapsed time and the progress bar. mediaPlayer.currentPosition.toLong(), // Playback speed // Determines the rate at which the elapsed time changes. playbackSpeed ) // isSeekable // Adding the SEEK_TO action indicates that seeking is supported // and makes the seekbar position marker draggable. If this is not // supplied seek will be disabled but progress will still be shown. .setActions(PlaybackStateCompat.ACTION_SEEK_TO) .build() )
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { mediaSession.setPlaybackState( new PlaybackStateCompat.Builder() .setState( PlaybackStateCompat.STATE_PLAYING, // Playback position // Used to update the elapsed time and the progress bar. mediaPlayer.currentPosition.toLong(), // Playback speed // Determines the rate at which the elapsed time changes. playbackSpeed ) // isSeekable // Adding the SEEK_TO action indicates that seeking is supported // and makes the seekbar position marker draggable. If this is not // supplied seek will be disabled but progress will still be shown. .setActions(PlaybackStateCompat.ACTION_SEEK_TO) .build() ); }

رفتار اعلان برنامه ویدیو
برنامههای ویدیویی یا برنامههای صوتی که از بازپخش محلی در پسزمینه پشتیبانی نمیکنند باید رفتار خاصی برای اعلانهای رسانه داشته باشند تا از بروز مشکل در ارسال فرمانهای رسانه در شرایطی که بازپخش پشتیبانی نمیشود جلوگیری شود:
- اعلان رسانه را هنگام پخش رسانه بهصورت محلی و زمانی که برنامه در پیشزمینه است پست کنید.
- وقتی برنامه در پسزمینه است، بازپخش محلی را موقتاً متوقف کنید و اعلان را ببندید.
- وقتی برنامه به پیشزمینه برمیگردد، بازپخش محلی باید ازسر گرفته شود و اعلان باید دوباره پست شود.
فعال کردن «تعویضکننده خروجی» در AndroidManifest.xml
برای فعال کردن «تعویضکننده خروجی»،
MediaTransferReceiver
باید به AndroidManifest.xml برنامه اضافه شود. اگر اینطور نباشد، این ویژگی
فعال نخواهد شد و پرچم ویژگی «از راه دور به محلی» نیز نامعتبر خواهد بود.
<application>
...
<receiver
android:name="androidx.mediarouter.media.MediaTransferReceiver"
android:exported="true">
</receiver>
...
</application>
MediaTransferReceiver
گیرنده همهفرستی است که انتقال رسانه را بین دستگاههای دارای میانای کاربر سیستم ممکن میکند. برای اطلاعات بیشتر، به مرجع MediaTransferReceiver
مراجعه کنید.
محلی به دور
وقتی کاربر پخش را از محلی به از دور تغییر میدهد، «کیت توسعه نرمافزار Cast»
جلسه Cast را بهطور خودکار شروع میکند. بااینحال، برنامهها باید تغییر از محلی به از دور را مدیریت کنند، برای مثال، پخش محلی را متوقف کنند و رسانه را در دستگاه «پخش محتوا» بار کنند. برنامهها باید بااستفاده از
onSessionStarted()
و
onSessionEnded()
بازخوانها به Cast
SessionManagerListener گوش دهند و هنگام دریافت بازخوانهای Cast
SessionManager
، کنش را مدیریت کنند. برنامهها باید مطمئن شوند که این برگشتیها وقتی
کادر گفتگوی «تعویضکننده خروجی» باز میشود و برنامه در پیشزمینه نیست همچنان فعال هستند.
بهروزرسانی SessionManagerListener برای پخش محتوای پسزمینهای
تجربه قدیمی Cast درحالحاضر از محلی به دوردست وقتی برنامه در پیشزمینه است پشتیبانی میکند. تجربه معمول «پخش محتوا» زمانی شروع میشود که کاربران روی نماد «پخش محتوا» در برنامه کلیک میکنند و دستگاهی را برای جاریسازی رسانه انتخاب میکنند. در این مورد، برنامه باید در
SessionManagerListener
در onCreate() یا
onStart()
ثبت شود و شنونده در
onStop()
یا
onDestroy()
از فعالیت برنامه لغو ثبت شود.
با تجربه جدید پخش محتوا بااستفاده از «جابهجاگر برونداد»، برنامهها میتوانند
وقتی در پسزمینه هستند پخش محتوا را شروع کنند. این ویژگی بهویژه برای برنامههای صوتی که هنگام پخش در پسزمینه اعلان پست میکنند مفید است. برنامهها میتوانند
شنوندگان SessionManager
را در onCreate() سرویس ثبت کنند و در onDestroy()
سرویس ثبت آنها را لغو کنند. وقتی برنامه در پسزمینه است، برنامهها باید همیشه پاسخهای تماس محلی به راه دور را دریافت کنند (مثل onSessionStarted).
اگر برنامه از
MediaBrowserService استفاده میکند،
توصیه میشود SessionManagerListener
را در آنجا ثبت کنید.
class MyService : Service() { private var castContext: CastContext? = null protected fun onCreate() { castContext = CastContext.getSharedInstance(this) castContext .getSessionManager() .addSessionManagerListener(sessionManagerListener, CastSession::class.java) } protected fun onDestroy() { if (castContext != null) { castContext .getSessionManager() .removeSessionManagerListener(sessionManagerListener, CastSession::class.java) } } }
public class MyService extends Service { private CastContext castContext; @Override protected void onCreate() { castContext = CastContext.getSharedInstance(this); castContext .getSessionManager() .addSessionManagerListener(sessionManagerListener, CastSession.class); } @Override protected void onDestroy() { if (castContext != null) { castContext .getSessionManager() .removeSessionManagerListener(sessionManagerListener, CastSession.class); } } }
با این بهروزرسانی، وقتی برنامه در پسزمینه است، عملکرد محلی به دور یکسان با پخش محتوای معمولی است و برای جابهجایی از دستگاههای بلوتوث به دستگاههای «پخش محتوا» به کار اضافی نیاز نیست.
از دور به محلی
«تعویضکننده خروجی» امکان انتقال از پخش از دور به
بلندگوی تلفن یا دستگاه بلوتوث محلی را فراهم میکند. با تنظیم پرچم
setRemoteToLocalEnabled
روی true در CastOptions میتوان این ویژگی را فعال کرد.
در مواردی که دستگاه فرستنده فعلی به جلسه موجود با
چند فرستنده میپیوندد و برنامه باید بررسی کند که آیا رسانه فعلی مجاز به
انتقال محلی است یا نه، برنامهها باید از onTransferred
بازخوان SessionTransferCallback
برای بررسی SessionState استفاده کنند.
پرچم setRemoteToLocalEnabled را تنظیم کنید
CastOptions.Builder
setRemoteToLocalEnabled را ارائه میدهد تا بلندگوی تلفن و دستگاههای بلوتوث محلی را بهعنوان هدفهای انتقال به
در کادر گفتگوی «تعویضکننده خروجی» درصورت وجود جلسه «پخش» فعال نشان دهد یا پنهان کند.
class CastOptionsProvider : OptionsProvider { fun getCastOptions(context: Context?): CastOptions { ... return Builder() ... .setRemoteToLocalEnabled(true) .build() } }
public class CastOptionsProvider implements OptionsProvider { @Override public CastOptions getCastOptions(Context context) { ... return new CastOptions.Builder() ... .setRemoteToLocalEnabled(true) .build() } }
ادامه پخش محلی
برنامههایی که از راه دور به محلی پشتیبانی میکنند باید SessionTransferCallback
را ثبت کنند تا هنگام وقوع رویداد مطلع شوند و بتوانند بررسی کنند که آیا رسانه باید
اجازه انتقال و ادامه پخش محلی را داشته باشد یا خیر.
CastContext#addSessionTransferCallback(SessionTransferCallback)
به برنامه اجازه میدهد SessionTransferCallback
خود را ثبت کند و وقتی فرستنده به
بازپخش محلی منتقل میشود، به onTransferred و onTransferFailed گوش کند.
پساز اینکه برنامه SessionTransferCallback خود را لغو ثبت کرد،
برنامه دیگر SessionTransferCallback
دریافت نخواهد کرد.
SessionTransferCallback
افزونهای از SessionManagerListener
پاسخبهتماسهای موجود است و پساز راهاندازی onSessionEnded راهاندازی میشود. ترتیب پاسخهای تماس از راه دور به محلی بهاینصورت است:
onTransferringonSessionEndingonSessionEndedonTransferred
ازآنجاییکه وقتی برنامه در پسزمینه است و محتوا پخش میکند، تراشه اعلان رسانه میتواند «تعویضکننده خروجی» را باز کند، برنامهها باید انتقال به محلی را بسته به اینکه از بازپخش پسزمینهای پشتیبانی میکنند یا نه، بهصورت متفاوتی مدیریت کنند. درصورت
ناموفق بودن انتقال، onTransferFailed
هرزمان که خطا رخ دهد فعال میشود.
برنامههایی که از بازپخش پسزمینهای پشتیبانی میکنند
برای برنامههایی که از بازپخش در پسزمینه پشتیبانی میکنند (معمولاً برنامههای صوتی)، توصیه میشود از Service (برای مثال MediaBrowserService) استفاده شود. سرویسها باید به onTransferred
بازخوان گوش دهند و بازپخش را بهصورت محلی هم زمانی که برنامه در پیشزمینه است و هم زمانی که در پسزمینه است ازسر بگیرند.
class MyService : Service() { private var castContext: CastContext? = null private var sessionTransferCallback: SessionTransferCallback? = null protected fun onCreate() { castContext = CastContext.getSharedInstance(this) castContext.getSessionManager() .addSessionManagerListener(sessionManagerListener, CastSession::class.java) sessionTransferCallback = MySessionTransferCallback() castContext.addSessionTransferCallback(sessionTransferCallback) } protected fun onDestroy() { if (castContext != null) { castContext.getSessionManager() .removeSessionManagerListener(sessionManagerListener, CastSession::class.java) if (sessionTransferCallback != null) { castContext.removeSessionTransferCallback(sessionTransferCallback) } } } class MySessionTransferCallback : SessionTransferCallback() { fun onTransferring(@SessionTransferCallback.TransferType transferType: Int) { // Perform necessary steps prior to onTransferred } fun onTransferred(@SessionTransferCallback.TransferType transferType: Int, sessionState: SessionState?) { if (transferType == SessionTransferCallback.TRANSFER_TYPE_FROM_REMOTE_TO_LOCAL) { // Remote stream is transferred to the local device. // Retrieve information from the SessionState to continue playback on the local player. } } fun onTransferFailed(@SessionTransferCallback.TransferType transferType: Int, @SessionTransferCallback.TransferFailedReason transferFailedReason: Int) { // Handle transfer failure. } } }
public class MyService extends Service { private CastContext castContext; private SessionTransferCallback sessionTransferCallback; @Override protected void onCreate() { castContext = CastContext.getSharedInstance(this); castContext.getSessionManager() .addSessionManagerListener(sessionManagerListener, CastSession.class); sessionTransferCallback = new MySessionTransferCallback(); castContext.addSessionTransferCallback(sessionTransferCallback); } @Override protected void onDestroy() { if (castContext != null) { castContext.getSessionManager() .removeSessionManagerListener(sessionManagerListener, CastSession.class); if (sessionTransferCallback != null) { castContext.removeSessionTransferCallback(sessionTransferCallback); } } } public static class MySessionTransferCallback extends SessionTransferCallback { public MySessionTransferCallback() {} @Override public void onTransferring(@SessionTransferCallback.TransferType int transferType) { // Perform necessary steps prior to onTransferred } @Override public void onTransferred(@SessionTransferCallback.TransferType int transferType, SessionState sessionState) { if (transferType==SessionTransferCallback.TRANSFER_TYPE_FROM_REMOTE_TO_LOCAL) { // Remote stream is transferred to the local device. // Retrieve information from the SessionState to continue playback on the local player. } } @Override public void onTransferFailed(@SessionTransferCallback.TransferType int transferType, @SessionTransferCallback.TransferFailedReason int transferFailedReason) { // Handle transfer failure. } } }
برنامههایی که از بازپخش پسزمینهای پشتیبانی نمیکنند
برای برنامههایی که از بازپخش پسزمینهای پشتیبانی نمیکنند (معمولاً برنامههای ویدیویی)، توصیه میشود که به onTransferred
بازخوانی گوش دهید و اگر برنامه در پیشزمینه است، بازپخش را بهصورت محلی ازسر بگیرید.
اگر برنامه در پسزمینه باشد، باید بازپخش را موقتاً متوقف کند و اطلاعات لازم را از SessionState ذخیره کند (برای مثال، فراداده رسانه و موقعیت بازپخش). وقتی برنامه از پسزمینه به پیشزمینه میآید، پخش محلی باید با اطلاعات ذخیرهشده ادامه یابد.
class MyActivity : AppCompatActivity() { private var castContext: CastContext? = null private var sessionTransferCallback: SessionTransferCallback? = null protected fun onCreate() { castContext = CastContext.getSharedInstance(this) castContext.getSessionManager() .addSessionManagerListener(sessionManagerListener, CastSession::class.java) sessionTransferCallback = MySessionTransferCallback() castContext.addSessionTransferCallback(sessionTransferCallback) } protected fun onDestroy() { if (castContext != null) { castContext.getSessionManager() .removeSessionManagerListener(sessionManagerListener, CastSession::class.java) if (sessionTransferCallback != null) { castContext.removeSessionTransferCallback(sessionTransferCallback) } } } class MySessionTransferCallback : SessionTransferCallback() { fun onTransferring(@SessionTransferCallback.TransferType transferType: Int) { // Perform necessary steps prior to onTransferred } fun onTransferred(@SessionTransferCallback.TransferType transferType: Int, sessionState: SessionState?) { if (transferType == SessionTransferCallback.TRANSFER_TYPE_FROM_REMOTE_TO_LOCAL) { // Remote stream is transferred to the local device. // Retrieve information from the SessionState to continue playback on the local player. } } fun onTransferFailed(@SessionTransferCallback.TransferType transferType: Int, @SessionTransferCallback.TransferFailedReason transferFailedReason: Int) { // Handle transfer failure. } } }
public class MyActivity extends AppCompatActivity { private CastContext castContext; private SessionTransferCallback sessionTransferCallback; @Override protected void onCreate() { castContext = CastContext.getSharedInstance(this); castContext .getSessionManager() .addSessionManagerListener(sessionManagerListener, CastSession.class); sessionTransferCallback = new MySessionTransferCallback(); castContext.addSessionTransferCallback(sessionTransferCallback); } @Override protected void onDestroy() { if (castContext != null) { castContext .getSessionManager() .removeSessionManagerListener(sessionManagerListener, CastSession.class); if (sessionTransferCallback != null) { castContext.removeSessionTransferCallback(sessionTransferCallback); } } } public static class MySessionTransferCallback extends SessionTransferCallback { public MySessionTransferCallback() {} @Override public void onTransferring(@SessionTransferCallback.TransferType int transferType) { // Perform necessary steps prior to onTransferred } @Override public void onTransferred(@SessionTransferCallback.TransferType int transferType, SessionState sessionState) { if (transferType==SessionTransferCallback.TRANSFER_TYPE_FROM_REMOTE_TO_LOCAL) { // Remote stream is transferred to the local device. // Retrieve information from the SessionState to continue playback on the local player. } } @Override public void onTransferFailed(@SessionTransferCallback.TransferType int transferType, @SessionTransferCallback.TransferFailedReason int transferFailedReason) { // Handle transfer failure. } } }
ازراهدور به ازراهدور
«تعویضکننده خروجی» از قابلیت گسترش به چندین دستگاه بلندگوی سازگار با Cast برای برنامههای صوتی بااستفاده از «گسترش جاریسازی» پشتیبانی میکند.
برنامههای صوتی برنامههایی هستند که از Google Cast برای صدا در تنظیمات برنامه گیرنده در «کنسول توسعهدهندگان کیت توسعه نرمافزار Google Cast» پشتیبانی میکنند

«توسعه جاریسازی» با بلندگو
برنامههای صوتی که از «تعویضکننده خروجی» استفاده میکنند میتوانند درطول جلسه Cast بااستفاده از «گسترش جاریسازی»، صدا را به چندین دستگاه بلندگوی سازگار با Cast گسترش دهند.
این ویژگی توسط پلاتفرم «پخش محتوا» پشتیبانی میشود و اگر برنامه از میانای کاربری پیشفرض استفاده کند، نیازی به تغییرات بیشتر ندارد. اگر از میانای کاربر سفارشی استفاده میشود، برنامه باید میانای کاربر را بهروز کند تا نشان دهد برنامه درحال ارسال محتوا به گروه است.

برای دریافت نام گروه ازهم بازشده جدید درطول ازهم بازشدن جاریسازی،
بااستفاده از
CastSession#addCastListener،
Cast.Listener
را ثبت کنید.
سپس درطول تماس برگشتی onDeviceNameChanged تماس بگیرید
CastSession#getCastDevice()
class MyActivity : Activity() { private var mCastSession: CastSession? = null private lateinit var mCastContext: CastContext private lateinit var mSessionManager: SessionManager private val mSessionManagerListener: SessionManagerListener<CastSession> = SessionManagerListenerImpl() private val mCastListener = CastListener() private inner class SessionManagerListenerImpl : SessionManagerListener<CastSession?> { override fun onSessionStarting(session: CastSession?) {} override fun onSessionStarted(session: CastSession?, sessionId: String) { addCastListener(session) } override fun onSessionStartFailed(session: CastSession?, error: Int) {} override fun onSessionSuspended(session: CastSession?, reason Int) { removeCastListener() } override fun onSessionResuming(session: CastSession?, sessionId: String) {} override fun onSessionResumed(session: CastSession?, wasSuspended: Boolean) { addCastListener(session) } override fun onSessionResumeFailed(session: CastSession?, error: Int) {} override fun onSessionEnding(session: CastSession?) {} override fun onSessionEnded(session: CastSession?, error: Int) { removeCastListener() } } private inner class CastListener : Cast.Listener() { override fun onDeviceNameChanged() { mCastSession?.let { val castDevice = it.castDevice val deviceName = castDevice.friendlyName // Update UIs with the new cast device name. } } } private fun addCastListener(castSession: CastSession) { mCastSession = castSession mCastSession?.addCastListener(mCastListener) } private fun removeCastListener() { mCastSession?.removeCastListener(mCastListener) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mCastContext = CastContext.getSharedInstance(this) mSessionManager = mCastContext.sessionManager mSessionManager.addSessionManagerListener(mSessionManagerListener, CastSession::class.java) } override fun onDestroy() { super.onDestroy() mSessionManager.removeSessionManagerListener(mSessionManagerListener, CastSession::class.java) } }
public class MyActivity extends Activity { private CastContext mCastContext; private CastSession mCastSession; private SessionManager mSessionManager; private SessionManagerListener<CastSession> mSessionManagerListener = new SessionManagerListenerImpl(); private Cast.Listener mCastListener = new CastListener(); private class SessionManagerListenerImpl implements SessionManagerListener<CastSession> { @Override public void onSessionStarting(CastSession session) {} @Override public void onSessionStarted(CastSession session, String sessionId) { addCastListener(session); } @Override public void onSessionStartFailed(CastSession session, int error) {} @Override public void onSessionSuspended(CastSession session, int reason) { removeCastListener(); } @Override public void onSessionResuming(CastSession session, String sessionId) {} @Override public void onSessionResumed(CastSession session, boolean wasSuspended) { addCastListener(session); } @Override public void onSessionResumeFailed(CastSession session, int error) {} @Override public void onSessionEnding(CastSession session) {} @Override public void onSessionEnded(CastSession session, int error) { removeCastListener(); } } private class CastListener extends Cast.Listener { @Override public void onDeviceNameChanged() { if (mCastSession == null) { return; } CastDevice castDevice = mCastSession.getCastDevice(); String deviceName = castDevice.getFriendlyName(); // Update UIs with the new cast device name. } } private void addCastListener(CastSession castSession) { mCastSession = castSession; mCastSession.addCastListener(mCastListener); } private void removeCastListener() { if (mCastSession != null) { mCastSession.removeCastListener(mCastListener); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mCastContext = CastContext.getSharedInstance(this); mSessionManager = mCastContext.getSessionManager(); mSessionManager.addSessionManagerListener(mSessionManagerListener, CastSession.class); } @Override protected void onDestroy() { super.onDestroy(); mSessionManager.removeSessionManagerListener(mSessionManagerListener, CastSession.class); } }
درحال آزمایش دور به دور
برای آزمایش کردن ویژگی:
- محتوای خود را بااستفاده از پخش محتوای معمولی یا با محلی به دور در دستگاه سازگار با پخش محتوا پخش کنید.
- «گزینشگر برونداد» را بااستفاده از یکی از نقاط ورودی باز کنید.
- روی دستگاه سازگار با Cast دیگری تکضرب بزنید، برنامههای صوتی محتوا را به دستگاه دیگر گسترش میدهند و گروهی پویا ایجاد میکنند.
- دوباره روی دستگاه سازگار با Cast تکضرب بزنید، دستگاه از گروه پویا برداشته خواهد شد.