Pengalih Output adalah fitur Cast SDK yang memungkinkan transfer konten yang lancar antara pemutaran lokal dan jarak jauh, dimulai dengan Android 13. Tujuannya adalah membantu aplikasi pengirim mengontrol tempat konten diputar dengan mudah dan cepat.
Pengalih Output menggunakan library
MediaRouter untuk
mengalihkan pemutaran konten antara speaker ponsel, perangkat Bluetooth yang dipasangkan,
dan perangkat jarak jauh yang kompatibel untuk Cast. Kasus penggunaan dapat dibagi menjadi skenario berikut:
Download dan gunakan aplikasi contoh CastVideos-android sebagai referensi tentang cara menerapkan Pengalih Output di aplikasi Anda.
Pengalih Output harus diaktifkan untuk mendukung lokal ke jarak jauh, jarak jauh ke lokal, dan jarak jauh ke jarak jauh menggunakan langkah-langkah yang dibahas dalam panduan ini. Tidak ada langkah tambahan yang diperlukan untuk mendukung transfer antara speaker perangkat lokal dan perangkat Bluetooth yang dipasangkan.
UI Pengalih Output
Pengalih Output menampilkan perangkat lokal dan jarak jauh yang tersedia serta status perangkat saat ini, termasuk apakah perangkat dipilih, sedang terhubung, dan tingkat volume saat ini. Jika ada perangkat lain selain perangkat saat ini, mengklik perangkat lain akan memungkinkan Anda mentransfer pemutaran media ke perangkat yang dipilih.

Masalah umum
- Sesi Media yang dibuat untuk pemutaran lokal akan ditutup dan dibuat ulang saat beralih ke notifikasi Cast SDK.
Titik entri
Notifikasi media
Jika aplikasi memposting notifikasi media dengan
MediaSession untuk
pemutaran lokal (diputar secara lokal), sudut kanan atas notifikasi media
akan menampilkan chip notifikasi dengan nama perangkat (seperti speaker ponsel) tempat
konten saat ini diputar. Mengetuk chip notifikasi akan membuka UI sistem dialog Pengalih Output.

Setelan volume
UI sistem dialog Pengalih Output juga dapat dipicu dengan mengklik tombol volume fisik di perangkat, mengetuk ikon setelan di bagian bawah, dan mengetuk teks "Putar <Nama Aplikasi> di <Perangkat Cast>".

Ringkasan langkah
- Memastikan prasyarat terpenuhi
- Mengaktifkan Pengalih Output di AndroidManifest.xml
- Memperbarui SessionManagerListener untuk transmisi latar belakang
- Menambahkan dukungan untuk Jarak Jauh ke Jarak Jauh
- Menetapkan flag setRemoteToLocalEnabled
- Melanjutkan pemutaran secara lokal
Prasyarat
- Migrasikan aplikasi Android yang ada ke AndroidX.
- Perbarui
build.gradleaplikasi Anda untuk menggunakan versi minimum yang diperlukan dari Android Sender SDK untuk Pengalih Output:dependencies { ... implementation 'com.google.android.gms:play-services-cast-framework:21.2.0' ... }
- Aplikasi mendukung notifikasi media.
- Perangkat yang menjalankan Android 13.
Menyiapkan Notifikasi Media
Untuk menggunakan Pengalih Output,
aplikasi audio dan
video
harus membuat notifikasi media untuk menampilkan status pemutaran dan
kontrol untuk media mereka untuk pemutaran lokal. Hal ini memerlukan pembuatan
MediaSession,
menetapkan
MediaStyle
dengan token MediaSession's, dan menetapkan kontrol media pada
notifikasi.
Jika saat ini Anda tidak menggunakan MediaStyle dan MediaSession, cuplikan
di bawah menunjukkan cara menyiapkan keduanya dan panduan tersedia untuk menyiapkan callback sesi
media untuk
aplikasi audio dan
video:
// 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(); }

Selain itu, untuk mengisi notifikasi dengan informasi untuk media Anda,
Anda harus menambahkan
metadata dan status pemutaran media
ke MediaSession.
Untuk menambahkan metadata ke MediaSession, gunakan
setMetaData()
dan berikan semua konstanta
MediaMetadata yang relevan untuk
media Anda di
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() ); }

Untuk menambahkan status pemutaran ke MediaSession, gunakan
setPlaybackState()
dan berikan semua konstanta
PlaybackStateCompat
yang relevan untuk media Anda di
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() ); }

Perilaku notifikasi aplikasi video
Aplikasi video atau aplikasi audio yang tidak mendukung pemutaran lokal di latar belakang harus memiliki perilaku khusus untuk notifikasi media guna menghindari masalah saat mengirim perintah media dalam situasi yang tidak mendukung pemutaran:
- Posting notifikasi media saat memutar media secara lokal dan aplikasi berada di latar depan.
- Jeda pemutaran lokal dan tutup notifikasi saat aplikasi berada di latar belakang.
- Saat aplikasi kembali ke latar depan, pemutaran lokal harus dilanjutkan dan notifikasi harus diposting ulang.
Mengaktifkan Pengalih Output di AndroidManifest.xml
Untuk mengaktifkan Pengalih Output, MediaTransferReceiver
harus ditambahkan ke AndroidManifest.xml aplikasi. Jika tidak, fitur ini tidak akan diaktifkan dan flag fitur jarak jauh ke lokal juga akan tidak valid.
<application>
...
<receiver
android:name="androidx.mediarouter.media.MediaTransferReceiver"
android:exported="true">
</receiver>
...
</application>
The
MediaTransferReceiver
adalah penerima siaran yang memungkinkan transfer media antar-perangkat dengan sistem
UI. Lihat referensi MediaTransferReceiver
untuk mengetahui informasi selengkapnya.
Lokal ke jarak jauh
Saat pengguna mengalihkan pemutaran dari lokal ke jarak jauh, Cast SDK akan otomatis memulai sesi Cast. Namun, aplikasi perlu menangani pengalihan dari lokal ke jarak jauh, misalnya menghentikan pemutaran lokal dan memuat media di perangkat Cast. Aplikasi harus memproses Cast
SessionManagerListener,
menggunakan callback
onSessionStarted()
dan
onSessionEnded(), serta menangani tindakan saat menerima callback Cast
SessionManager. Aplikasi harus memastikan bahwa callback ini masih aktif saat dialog Pengalih Output dibuka dan aplikasi tidak berada di latar depan.
Memperbarui SessionManagerListener untuk transmisi latar belakang
Pengalaman Cast lama sudah mendukung lokal ke jarak jauh saat aplikasi berada di latar depan. Pengalaman Cast yang umum dimulai saat pengguna mengklik ikon Cast di aplikasi dan memilih perangkat untuk melakukan streaming media. Dalam hal ini, aplikasi harus
mendaftar ke
SessionManagerListener,
di onCreate() atau
onStart()
dan membatalkan pendaftaran pemroses di
onStop()
atau
onDestroy()
aktivitas aplikasi.
Dengan pengalaman baru transmisi menggunakan Pengalih Output, aplikasi dapat mulai melakukan transmisi saat berada di latar belakang. Hal ini sangat berguna untuk aplikasi audio yang memposting notifikasi saat diputar di latar belakang. Aplikasi dapat mendaftarkan
pemroses SessionManager
di onCreate() layanan dan membatalkan pendaftaran di onDestroy()
layanan. Aplikasi harus selalu menerima callback lokal ke jarak jauh (seperti
onSessionStarted)
saat aplikasi berada di latar belakang.
Jika aplikasi menggunakan
MediaBrowserService,
sebaiknya daftarkan SessionManagerListener
di sana.
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); } } }
Dengan update ini, lokal ke jarak jauh bertindak sama seperti transmisi konvensional saat aplikasi berada di latar belakang dan tidak diperlukan pekerjaan tambahan untuk beralih dari perangkat Bluetooth ke perangkat Cast.
Jarak jauh ke lokal
Pengalih Output memberikan kemampuan untuk mentransfer dari pemutaran jarak jauh ke speaker ponsel atau perangkat Bluetooth lokal. Hal ini dapat diaktifkan dengan menetapkan flag
setRemoteToLocalEnabled
ke true di CastOptions.
Untuk kasus saat perangkat pengirim saat ini bergabung dengan sesi yang ada dengan
beberapa pengirim dan aplikasi perlu memeriksa apakah media saat ini diizinkan untuk
ditransfer secara lokal, aplikasi harus menggunakan onTransferred
callback dari SessionTransferCallback
untuk memeriksa SessionState.
Menetapkan flag setRemoteToLocalEnabled
The CastOptions.Builder
menyediakan setRemoteToLocalEnabled untuk menampilkan atau menyembunyikan speaker ponsel dan perangkat Bluetooth lokal sebagai target transfer
di dialog Pengalih Output saat ada sesi Cast aktif.
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() } }
Melanjutkan pemutaran secara lokal
Aplikasi yang mendukung jarak jauh ke lokal harus mendaftarkan SessionTransferCallback
untuk mendapatkan notifikasi saat peristiwa terjadi sehingga dapat memeriksa apakah media harus diizinkan untuk ditransfer dan melanjutkan pemutaran secara lokal.
CastContext#addSessionTransferCallback(SessionTransferCallback)
memungkinkan aplikasi mendaftarkan SessionTransferCallback
dan memproses callback onTransferred dan onTransferFailed saat pengirim
ditransfer ke pemutaran lokal.
Setelah aplikasi membatalkan pendaftaran SessionTransferCallback,
aplikasi tidak akan lagi menerima SessionTransferCallback.
SessionTransferCallback
adalah ekstensi dari callback SessionManagerListener
yang ada dan dipicu setelah onSessionEnded dipicu. Urutan callback jarak jauh ke lokal adalah:
onTransferringonSessionEndingonSessionEndedonTransferred
Karena Pengalih Output dapat dibuka oleh chip notifikasi media saat aplikasi berada di latar belakang dan melakukan transmisi, aplikasi perlu menangani transfer ke lokal secara berbeda, bergantung pada apakah aplikasi mendukung pemutaran latar belakang atau tidak. Jika transfer gagal, onTransferFailedakan diaktifkan kapan saja terjadi error.
Aplikasi yang mendukung pemutaran latar belakang
Untuk aplikasi yang mendukung pemutaran di latar belakang (biasanya aplikasi audio), sebaiknya gunakan Service (misalnya MediaBrowserService). Layanan harus memproses callback onTransferred dan melanjutkan pemutaran secara lokal saat aplikasi berada di latar depan atau latar belakang.
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. } } }
Aplikasi yang tidak mendukung pemutaran latar belakang
Untuk aplikasi yang tidak mendukung pemutaran latar belakang (biasanya aplikasi video), sebaiknya
proses onTransferred
callback dan lanjutkan pemutaran secara lokal jika aplikasi berada di latar depan.
Jika aplikasi berada di latar belakang, aplikasi harus menjeda pemutaran dan menyimpan
informasi yang diperlukan dari SessionState
(misalnya, metadata media dan posisi pemutaran). Saat aplikasi berada di latar depan dari latar belakang, pemutaran lokal harus dilanjutkan dengan informasi yang disimpan.
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. } } }
Jarak jauh ke jarak jauh
Pengalih Output mendukung kemampuan untuk diperluas ke beberapa perangkat speaker yang kompatibel untuk Cast untuk aplikasi audio menggunakan Perluasan Streaming.
Aplikasi audio adalah aplikasi yang mendukung Google Cast untuk Audio di setelan Aplikasi Penerima di Konsol Developer Google Cast SDK

Perluasan Streaming dengan speaker
Aplikasi audio yang menggunakan Pengalih Output memiliki kemampuan untuk memperluas audio ke beberapa perangkat speaker yang kompatibel untuk Cast selama sesi Cast menggunakan Perluasan Streaming.
Fitur ini didukung oleh platform Cast dan tidak memerlukan perubahan lebih lanjut jika aplikasi menggunakan UI default. Jika UI kustom digunakan, aplikasi harus memperbarui UI untuk menunjukkan bahwa aplikasi melakukan transmisi ke grup.

Untuk mendapatkan nama grup yang diperluas baru selama perluasan streaming,
daftarkan
Cast.Listener
menggunakan
CastSession#addCastListener.
Kemudian, panggil
CastSession#getCastDevice()
selama callback onDeviceNameChanged.
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); } }
Menguji jarak jauh ke jarak jauh
Untuk menguji fitur ini:
- Transmisikan konten Anda ke perangkat yang kompatibel untuk Cast menggunakan transmisi konvensional atau dengan lokal ke jarak jauh.
- Buka Pengalih Output menggunakan salah satu titik entri.
- Ketuk perangkat lain yang kompatibel untuk Cast. Aplikasi audio akan memperluas konten ke perangkat tambahan, sehingga membuat grup dinamis.
- Ketuk perangkat yang kompatibel untuk Cast lagi, perangkat tersebut akan dihapus dari grup dinamis.