Bu geliştirici kılavuzunda, Google Cast desteğini Android cihazınıza nasıl ekleyeceğiniz açıklanmaktadır. Android Sender SDK'sı kullanan bir gönderen uygulaması.
Mobil cihaz veya dizüstü bilgisayar, oynatmayı kontrol eden gönderendir ve Google Cast cihazı, içeriği TV'de görüntüleyen Alıcıdır.
Gönderen çerçevesi, Cast sınıf kitaplığı ikili programını ve kaynaklar, gönderen üzerinde çalışma zamanında mevcut olana işaret eder. Gönderen uygulaması veya Yayın uygulaması, gönderende de çalışan bir uygulamayı ifade eder. Web Alıcı uygulaması Cast uyumlu cihazda çalışan HTML uygulamasını belirtir.
Gönderen çerçevesi, göndereni bilgilendirmek için eşzamansız bir geri çağırma tasarımı kullanır ve Cast uygulaması hayatının çeşitli durumları arasında geçiş yapmak için kullanılan döngüsünü de takip eder.
Uygulama akışı
Aşağıdaki adımlarda, bir gönderen için tipik üst düzey yürütme akışı açıklanmaktadır Android uygulaması:
- Cast çerçevesi otomatik olarak başlatılır
MediaRouter
Activity
yaşam döngüsüne göre cihaz keşfi. - Kullanıcı Yayınla düğmesini tıkladığında çerçeve, Yayınla iletişim kutusu gösterilir.
- Kullanıcı bir yayın cihazı seçtiğinde çerçeve, cihazın ilk birkaç adımını Yayın cihazındaki Web Alıcı uygulaması.
- Çerçeve, web sitesinin kapsayıcı olmadığını doğrulamak için gönderen uygulamasında geri çağırmaları Alıcı uygulaması kullanıma sunuldu.
- Bu çerçeve, gönderen ile web arasında bir iletişim kanalı oluşturur Alıcı uygulamalar.
- Çerçeve, web alıcısında medya oynatmayı yüklemek ve kontrol etmek için iletişim kanalını kullanır.
- Çerçeve, medya oynatma durumunu gönderen ve Web Alıcı: Kullanıcı, gönderen kullanıcı arayüzü işlemleri yaptığında çerçeve Web Alıcısı'na göndermek ve Web Alıcısı medya durumu güncellemeleri gönderdiğinde çerçeve, gönderen kullanıcı arayüzünün durumunu günceller.
- Kullanıcı Yayın cihazı bağlantısını kesmek için Yayın düğmesini tıkladığında çerçeve, gönderen uygulamasının Web Alıcısı ile bağlantısını keser.
Google Cast'teki tüm sınıfların, yöntemlerin ve etkinliklerin kapsamlı listesi için Android SDK; Google Cast Sender API Reference for Android. Aşağıdaki bölümlerde, Android uygulamanıza Cast'i eklemeniz için uygulanacak adımlar ele alınmaktadır.
Android manifestini yapılandırma
Uygulamanızın AndroidManifest.xml dosyasında, Cast SDK'sı için aşağıdaki öğeleri yapılandırmanız gerekir:
uses-sdk
Cast SDK'sının desteklediği minimum ve hedef Android API düzeylerini ayarlayın. Şu anda minimum API düzeyi 23, hedef API düzeyi ise 34'tür.
<uses-sdk
android:minSdkVersion="23"
android:targetSdkVersion="34" />
android:theme
Uygulamanızın temasını minimum Android SDK sürümüne göre ayarlayın. Örneğin, kendi temanızı uygulamıyorsanız Lollipop öncesi bir minimum Android SDK sürümünü hedeflerken Theme.AppCompat
'ün bir varyantını kullanmanız gerekir.
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat" >
...
</application>
Yayınlama Bağlamını Başlat
Çerçeve, tablodaki global bir tekil nesne (CastContext
) içerir.
tüm çerçevelerin etkileşimleri.
Uygulamanız, CastContext
tekil nesneyi başlatmak için gereken seçenekleri sağlamak amacıyla OptionsProvider
arayüzünü uygulamalıdır. OptionsProvider
, şunu sağlar:
CastOptions
seçenekleri içerir. En
Bunlardan en önemlisi, algoritmik verileri filtrelemek için kullanılan
en son sürümüne sahip olduğunu ve yayın oturumu başladığında Web Alıcı uygulamasını
başladı.
class CastOptionsProvider : OptionsProvider { override fun getCastOptions(context: Context): CastOptions { return Builder() .setReceiverApplicationId(context.getString(R.string.app_id)) .build() } override fun getAdditionalSessionProviders(context: Context): List<SessionProvider>? { return null } }
public class CastOptionsProvider implements OptionsProvider { @Override public CastOptions getCastOptions(Context context) { CastOptions castOptions = new CastOptions.Builder() .setReceiverApplicationId(context.getString(R.string.app_id)) .build(); return castOptions; } @Override public List<SessionProvider> getAdditionalSessionProviders(Context context) { return null; } }
Gönderen uygulamanın AndroidManifest.xml dosyasında, uygulanan OptionsProvider
'nin tam nitelikli adını bir meta veri alanı olarak beyan etmeniz gerekir:
<application>
...
<meta-data
android:name=
"com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="com.foo.CastOptionsProvider" />
</application>
CastContext.getSharedInstance()
şu durumlarda CastContext
geç başlatılır:
çağrılır.
class MyActivity : FragmentActivity() { override fun onCreate(savedInstanceState: Bundle?) { val castContext = CastContext.getSharedInstance(this) } }
public class MyActivity extends FragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { CastContext castContext = CastContext.getSharedInstance(this); } }
Cast UX Widget'ları
Cast çerçevesi, Cast Tasarımı'na uygun widget'lar sağlar. Yapılacaklar listesi:
Tanıtım Yer Paylaşımı: Çerçeve, özel bir Görünüm sağlar,
IntroductoryOverlay
, kullanıcının Yayınla düğmesine dikkatini göstermesi için yeni bir e-posta alırsınız. Sender uygulaması, Metni ve başlığın konumunu özelleştirin metin.Yayınla Düğmesi: Yayınla düğmesi, yayın cihazlarının kullanılabilirliğinden bağımsız olarak görünür. Kullanıcı Yayınla düğmesini ilk kez tıkladığında, bulunan cihazların listeleneceği bir Yayınla iletişim kutusu gösterilir. Kullanıcı Yayınla düğmesini tıkladığında Cihaz bağlıyken, geçerli medya meta verilerini (örneğin, başlığı, kayıt stüdyosunun adı ve küçük resim) veya kullanıcının yayın cihazıyla bağlantıyı kesin. "Yayın düğmesi" bazen "Yayın simgesi" olarak da adlandırılır.
Mini Kumanda: Kullanıcı içerik yayınlarken geçerli sayfadan ayrıldığında içerik sayfasını veya genişletilmiş denetleyiciyi, gönderen uygulamasındaki başka bir ekrana kullanıcıya izin vermek için ekranın altında mini kumanda görüntülenir. yayınlanan medya meta verilerini görebilir ve oynatmayı kontrol edebilirsiniz.
Genişletilmiş Denetleyici: Kullanıcı içerik yayınlarken medya bildirimini tıklarsa kullanıyorsanız genişletilmiş kumanda devreye girer ve her ekranda medya meta verilerini oynatıyordur ve kontrol etmek için bazı düğmeler sağlar medya oynatmaya başladı.
Bildirim: Yalnızca Android'de sunulur. Kullanıcı içerik yayınlarken ve gönderen uygulamasını sağlarsanız şu anda yayınlanan içeriği gösteren bir medya bildirimi medya meta verileri ve oynatma denetimleri gibi.
Kilit Ekranı: Yalnızca Android'de sunulur. Kullanıcı içerik yayınlarken (veya cihazda) gezindiğinde zaman aşımına uğrarsa) kilit ekranında o anda yayınlanan medya meta verilerini ve oynatma kontrollerini gösterir.
Aşağıdaki kılavuzda, bu widget'ların en iyi şekilde yararlanabilirsiniz.
Yayınla Düğmesi Ekle
Android
MediaRouter
API'ler, ikincil cihazlarda medya görüntüleme ve oynatmayı etkinleştirmek için tasarlanmıştır.
MediaRouter
API kullanan Android uygulamaları,
kullanıcıların, medya içeriğini oynatmak üzere bir medya yolu seçmelerine olanak tanımak için
Yayın cihazı gibi ikincil bir cihaz.
Bu çerçeve,
MediaRouteButton
olarak
Cast button
çok kolay. Öncelikle, xml dosyasına menünüzü tanımlayan bir menü öğesi veya MediaRouteButton
eklemeniz ve bunu çerçeveye bağlamak için CastButtonFactory
kullanmanız gerekir.
// To add a Cast button, add the following snippet.
// menu.xml
<item
android:id="@+id/media_route_menu_item"
android:title="@string/media_route_menu_title"
app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
app:showAsAction="always" />
// Then override the onCreateOptionMenu() for each of your activities. // MyActivity.kt override fun onCreateOptionsMenu(menu: Menu): Boolean { super.onCreateOptionsMenu(menu) menuInflater.inflate(R.menu.main, menu) CastButtonFactory.setUpMediaRouteButton( applicationContext, menu, R.id.media_route_menu_item ) return true }
// Then override the onCreateOptionMenu() for each of your activities. // MyActivity.java @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.main, menu); CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), menu, R.id.media_route_menu_item); return true; }
Bu durumda, Activity
cihazınız
FragmentActivity
,
buraya bir
MediaRouteButton
uygulayın.
// activity_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal" >
<androidx.mediarouter.app.MediaRouteButton
android:id="@+id/media_route_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:mediaRouteTypes="user"
android:visibility="gone" />
</LinearLayout>
// MyActivity.kt override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_layout) mMediaRouteButton = findViewById<View>(R.id.media_route_button) as MediaRouteButton CastButtonFactory.setUpMediaRouteButton(applicationContext, mMediaRouteButton) mCastContext = CastContext.getSharedInstance(this) }
// MyActivity.java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_layout); mMediaRouteButton = (MediaRouteButton) findViewById(R.id.media_route_button); CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), mMediaRouteButton); mCastContext = CastContext.getSharedInstance(this); }
Yayınla düğmesinin görünümünü bir tema kullanarak ayarlamak için bkz. Yayınla Düğmesini özelleştirin.
Cihaz bulmayı yapılandırın
Cihaz bulma tamamen
CastContext
.
CastContext başlatılırken, gönderen uygulama Web Alıcısı'nı belirtir
uygulama kimliği ve isteğe bağlı olarak ayara göre ad alanı filtrelemesi isteyebilir
supportedNamespaces
inç
CastOptions
CastContext
, dahili olarak MediaRouter
öğesine referans veriyor ve çalışmaya başlayacak
aşağıdaki koşullar altında keşfetme sürecini destekler:
- Cihaz keşif gecikmesini ve kullanıyorsanız keşif zaman zaman otomatik olarak Gönderen uygulaması ön plana geçer.
- Yayınlama iletişim kutusu açık.
- Cast SDK'sı bir Cast oturumunu kurtarmaya çalışıyor.
Yayınla iletişim kutusu kapatıldığında veya arka plana girer.
class CastOptionsProvider : OptionsProvider { companion object { const val CUSTOM_NAMESPACE = "urn:x-cast:custom_namespace" } override fun getCastOptions(appContext: Context): CastOptions { val supportedNamespaces: MutableList<String> = ArrayList() supportedNamespaces.add(CUSTOM_NAMESPACE) return CastOptions.Builder() .setReceiverApplicationId(context.getString(R.string.app_id)) .setSupportedNamespaces(supportedNamespaces) .build() } override fun getAdditionalSessionProviders(context: Context): List<SessionProvider>? { return null } }
class CastOptionsProvider implements OptionsProvider { public static final String CUSTOM_NAMESPACE = "urn:x-cast:custom_namespace"; @Override public CastOptions getCastOptions(Context appContext) { List<String> supportedNamespaces = new ArrayList<>(); supportedNamespaces.add(CUSTOM_NAMESPACE); CastOptions castOptions = new CastOptions.Builder() .setReceiverApplicationId(context.getString(R.string.app_id)) .setSupportedNamespaces(supportedNamespaces) .build(); return castOptions; } @Override public List<SessionProvider> getAdditionalSessionProviders(Context context) { return null; } }
Oturum yönetiminin işleyiş şekli
Cast SDK'sı, Cast oturumu, Bir cihaza bağlanma, Web'i başlatma (veya Web'e katılma) adımlarını birleştiren kuruluş Alıcı uygulama, bu uygulamaya bağlanma ve medya kontrol kanalını başlatma. Web Alıcısını göster Uygulama yaşam döngüsü kılavuzu daha fazla bilgi edinmek için Yardım Merkezi'ni ziyaret edebilirsiniz.
Oturumlar sınıf tarafından yönetilir
SessionManager
uygulamanızın
CastContext.getSessionManager()
.
Tekil oturumlar, Session
sınıfının alt sınıflarıyla temsil edilir.
Örneğin,
CastSession
Yayın cihazlarıyla ilgili oturumları temsil eder. Uygulamanız şu anda etkin
Oturumu şunu kullanarak yayınla:
SessionManager.getCurrentCastSession()
.
Uygulamanız
SessionManagerListener
oluşturma, askıya alma, devam ettirme ve gibi oturum etkinliklerini
feshedilebilir. Çerçeve, oturum etkinken anormal/ani bir sonlandırmadan otomatik olarak devam etmeyi dener.
Oturumlar, kullanıcı hareketlerine göre otomatik olarak oluşturulur ve kısaltılır
iletişim kutusunu MediaRouter
Uygulamalar, Cast başlatma hatalarını daha iyi anlamak için oturum başlatma hatasını CastReasonCodes
olarak dönüştürmek üzere CastContext#getCastReasonCodeForCastStatusCode(int)
kullanabilir.
Bazı oturum başlatma hatalarının (ör. CastReasonCodes#CAST_CANCELLED
) mevcut olduğunu lütfen unutmayın
Amaçlanan davranışlardır ve hata olarak günlüğe kaydedilmemelidir.
Oturumla ilgili olarak yapılan değişiklikleri bilmeniz gerekiyorsa
SessionManagerListener
. Bu örnekte bir
Activity
içinde CastSession
.
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 inner class SessionManagerListenerImpl : SessionManagerListener<CastSession?> { override fun onSessionStarting(session: CastSession?) {} override fun onSessionStarted(session: CastSession?, sessionId: String) { invalidateOptionsMenu() } override fun onSessionStartFailed(session: CastSession?, error: Int) { val castReasonCode = mCastContext.getCastReasonCodeForCastStatusCode(error) // Handle error } override fun onSessionSuspended(session: CastSession?, reason Int) {} override fun onSessionResuming(session: CastSession?, sessionId: String) {} override fun onSessionResumed(session: CastSession?, wasSuspended: Boolean) { invalidateOptionsMenu() } override fun onSessionResumeFailed(session: CastSession?, error: Int) {} override fun onSessionEnding(session: CastSession?) {} override fun onSessionEnded(session: CastSession?, error: Int) { finish() } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mCastContext = CastContext.getSharedInstance(this) mSessionManager = mCastContext.sessionManager mSessionManager.addSessionManagerListener(mSessionManagerListener, CastSession::class.java) } override fun onResume() { super.onResume() mCastSession = mSessionManager.currentCastSession } 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 class SessionManagerListenerImpl implements SessionManagerListener<CastSession> { @Override public void onSessionStarting(CastSession session) {} @Override public void onSessionStarted(CastSession session, String sessionId) { invalidateOptionsMenu(); } @Override public void onSessionStartFailed(CastSession session, int error) { int castReasonCode = mCastContext.getCastReasonCodeForCastStatusCode(error); // Handle error } @Override public void onSessionSuspended(CastSession session, int reason) {} @Override public void onSessionResuming(CastSession session, String sessionId) {} @Override public void onSessionResumed(CastSession session, boolean wasSuspended) { invalidateOptionsMenu(); } @Override public void onSessionResumeFailed(CastSession session, int error) {} @Override public void onSessionEnding(CastSession session) {} @Override public void onSessionEnded(CastSession session, int error) { finish(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mCastContext = CastContext.getSharedInstance(this); mSessionManager = mCastContext.getSessionManager(); mSessionManager.addSessionManagerListener(mSessionManagerListener, CastSession.class); } @Override protected void onResume() { super.onResume(); mCastSession = mSessionManager.getCurrentCastSession(); } @Override protected void onDestroy() { super.onDestroy(); mSessionManager.removeSessionManagerListener(mSessionManagerListener, CastSession.class); } }
Akış aktarma
Akış aktarımının temeli oturum durumunu korumaktır. Bu yöntemde kullanıcılar sesli komutları, Google Home'u kullanarak mevcut ses ve video akışlarını cihazlar arasında taşıyabilir uygulama veya akıllı ekranlar. Medya, bir cihazda (kaynak) duruyor ve başka bir cihazda (kaynaktaki) devam ediyor hedef). En son donanım yazılımına sahip Cast cihazları bir akış aktarımı.
Akış aktarımı veya genişletme sırasında yeni hedef cihazı almak için
bir kaydettirmek
Cast.Listener
her bir arama terimi için
CastSession#addCastListener
.
Ardından, onDeviceNameChanged
geri arama sırasında CastSession#getCastDevice()
'ı arayın.
Görüntüleyin Web Alıcısında akış aktarımı konulu videomuzu izleyin.
Otomatik yeniden bağlanma
Bu çerçeve,
ReconnectionService
Bu ayar, gönderen uygulaması tarafından yeniden bağlanmayı yönetmek için
Örneğin:
- Geçici kablosuz ağ kaybından kurtulma
- Cihaz uyku modundan kurtarma
- Uygulamayı arka plana aldıktan sonra kurtarma
- Uygulama kilitlenirse kurtar
Bu hizmet varsayılan olarak etkindir ve CastOptions.Builder
'te devre dışı bırakılabilir.
Otomatik birleştirme yapılırsa bu hizmet otomatik olarak uygulamanızın manifest dosyasıyla birleştirilebilir gradle dosyanızda etkin.
Çerçeve, medya oturumu olduğunda hizmeti başlatır ve durdurur sona erecektir.
Medya Denetimi nasıl çalışır?
Cast çerçevesi,
RemoteMediaPlayer
Cast 2.x'teki sınıf lehine yeni bir sınıf
RemoteMediaClient
,
Bu API, aynı işlevselliği daha kullanışlı bir dizi API'de sağlar ve
GoogleApiClient'ı aktarmak zorunda kalmaktan kaçınır.
Uygulamanız
CastSession
medya ad alanını destekleyen bir Web Alıcı uygulamasına sahip olan
RemoteMediaClient
, çerçeve tarafından otomatik olarak oluşturulur; uygulamanız
CastSession
üzerinde getRemoteMediaClient()
yöntemini çağırarak erişin
örneğidir.
Web alıcısına istek gönderen tüm RemoteMediaClient
yöntemleri, bu isteği izlemek için kullanılabilecek bir PendingResult nesnesi döndürür.
RemoteMediaClient
örneğinin, uygulamanızın birden fazla bölümü ve çerçevenin bazı dahili bileşenleri (ör. kalıcı mini denetleyiciler ve bildirim hizmeti) tarafından paylaşılabileceği beklenir.
Bu amaçla, bu örnek birden fazla
RemoteMediaClient.Listener
Medya meta verilerini ayarlama
İlgili içeriği oluşturmak için kullanılan
MediaMetadata
class, Yayınlamak istediğiniz medya öğesiyle ilgili bilgileri temsil eder. İlgili içeriği oluşturmak için kullanılan
aşağıdaki örnek, bir filmin yeni MediaMetadata örneğini oluşturur ve
başlık, alt başlık ve iki resim.
val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE) movieMetadata.putString(MediaMetadata.KEY_TITLE, mSelectedMedia.getTitle()) movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, mSelectedMedia.getStudio()) movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia.getImage(0)))) movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia.getImage(1))))
MediaMetadata movieMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE); movieMetadata.putString(MediaMetadata.KEY_TITLE, mSelectedMedia.getTitle()); movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, mSelectedMedia.getStudio()); movieMetadata.addImage(new WebImage(Uri.parse(mSelectedMedia.getImage(0)))); movieMetadata.addImage(new WebImage(Uri.parse(mSelectedMedia.getImage(1))));
Görüntüleyin Resim Seçimi izin verilebilir.
Medya yükle
Uygulamanız, aşağıdaki kodda gösterildiği gibi bir medya öğesi yükleyebilir. Öncelikle, bir MediaInfo
örneği oluşturmak için medya meta verileriyle MediaInfo.Builder
kullanın. Şunu edinin:
RemoteMediaClient
geçerli CastSession
öğesinden sonra MediaInfo
öğesini
RemoteMediaClient
. Oynatmak, duraklatmak ve diğer işlemleri yapmak için RemoteMediaClient
kullanın
Web Alıcısı'nda çalışan bir medya oynatıcı uygulamasını kontrol edebilir.
val mediaInfo = MediaInfo.Builder(mSelectedMedia.getUrl()) .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) .setContentType("videos/mp4") .setMetadata(movieMetadata) .setStreamDuration(mSelectedMedia.getDuration() * 1000) .build() val remoteMediaClient = mCastSession.getRemoteMediaClient() remoteMediaClient.load(MediaLoadRequestData.Builder().setMediaInfo(mediaInfo).build())
MediaInfo mediaInfo = new MediaInfo.Builder(mSelectedMedia.getUrl()) .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) .setContentType("videos/mp4") .setMetadata(movieMetadata) .setStreamDuration(mSelectedMedia.getDuration() * 1000) .build(); RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient(); remoteMediaClient.load(new MediaLoadRequestData.Builder().setMediaInfo(mediaInfo).build());
Medya parçalarını kullanma bölümüne de göz atın.
4K video biçimi
Medyanızın hangi video biçimini gösterdiğini kontrol etmek için şunu kullanın:
getVideoInfo()
almak için MediaStatus'a gidip
VideoInfo
.
Bu örnek, HDR TV biçiminin türünü ve ekran yüksekliğini içerir
ve genişliği piksel cinsinden belirtmektedir. 4K biçiminin varyantları sabit değerlerle gösterilir
HDR_TYPE_*
.
Birden fazla cihaza uzaktan bildirim gönderme
Bir kullanıcı yayın yaparken aynı ağdaki diğer Android cihazlar oynatmayı kontrol etmelerine olanak tanımak için bir bildirim. Cihazı olan herkes bu tür bildirimleri aldığında, bu bildirimleri Ayarlar'dan söz konusu cihaz için devre dışı bırakabilirsiniz uygulaması > Google Cast > Uzaktan kumanda bildirimlerini göster. (Bildirimler, Ayarlar uygulamasına giden bir kısayol içerir.) Daha fazla bilgi için bkz. Uzaktan kumanda bildirimlerini yayınlayın.
Mini kumanda ekle
Cast Tasarımına göre Yapılacaklar listesi gönderen uygulaması, mini denetleyici geçerli içerik sayfasından ayrıldığında ve diğer bir bölümüdür. Mini kumanda, ekranda görünen bir hatırlatıcı sağlar. Geçerli Cast oturumunun kullanıcısına gönderilir. Mini kumandaya dokunduğunuzda kullanıcı Cast tam ekran genişletilmiş denetleyici görünümüne dönebilir.
Çerçeve, mini denetleyiciyi göstermek istediğiniz her etkinliğin düzen dosyasının alt kısmına ekleyebileceğiniz özel bir görünüm (MiniControllerFragment) sağlar.
<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" />
Gönderen uygulamanız bir video veya ses canlı yayını oynatırken SDK, oynatma/duraklatma düğmesi yerine otomatik olarak bir oynat/durdur düğmesi görüntüler mini kumandada.
Bu özel görünümün başlığının ve alt başlığının metin görünümünü ayarlamak için ve düğmeleri seçmek için bkz. Mini Kumanda'yı özelleştirin.
Genişletilmiş denetleyici ekle
Google Cast Tasarım Kontrol Listesi, bir gönderen uygulamasının genişletilmiş bir denetleyici medya içeriği yayınlamada fayda var. Genişletilmiş denetleyici, için de geçerlidir.
Cast SDK'sı, genişletilmiş denetleyici için
ExpandedControllerActivity
.
Bu, Yayınla düğmesi eklemek için alt sınıfa girmeniz gereken soyut bir sınıftır.
Öncelikle, genişletilmiş denetleyicinin sağlaması için yeni bir menü kaynak dosyası oluşturun Yayınla düğmesi:
<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>
ExpandedControllerActivity
sınıfını genişleten yeni bir sınıf oluşturun.
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 } }
public class ExpandedControlsActivity extends ExpandedControllerActivity { @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.expanded_controller, menu); CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item); return true; } }
Ardından, yeni etkinliğinizi uygulama manifest dosyasında application
etiketi içinde beyan edin:
<application>
...
<activity
android:name=".expandedcontrols.ExpandedControlsActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:theme="@style/Theme.CastVideosDark"
android:screenOrientation="portrait"
android:parentActivityName="com.google.sample.cast.refplayer.VideoBrowserActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
...
</application>
CastOptionsProvider
öğesini düzenleyip NotificationOptions
ve
CastMediaOptions
kullanarak hedef aktiviteyi yeni etkinliğinize ayarlayın:
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() }
public CastOptions getCastOptions(Context context) { NotificationOptions notificationOptions = new NotificationOptions.Builder() .setTargetActivityClassName(ExpandedControlsActivity.class.getName()) .build(); CastMediaOptions mediaOptions = new CastMediaOptions.Builder() .setNotificationOptions(notificationOptions) .setExpandedControllerActivityClassName(ExpandedControlsActivity.class.getName()) .build(); return new CastOptions.Builder() .setReceiverApplicationId(context.getString(R.string.app_id)) .setCastMediaOptions(mediaOptions) .build(); }
Aşağıdakileri görüntülemek için LocalPlayerActivity
loadRemoteMedia
yöntemini güncelleyin
uzak medya yüklendiğinde yeni etkinlik:
private fun loadRemoteMedia(position: Int, autoPlay: Boolean) { 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(mSelectedMedia) .setAutoplay(autoPlay) .setCurrentTime(position.toLong()).build() ) }
private void loadRemoteMedia(int position, boolean autoPlay) { if (mCastSession == null) { return; } final RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient(); if (remoteMediaClient == null) { return; } remoteMediaClient.registerCallback(new RemoteMediaClient.Callback() { @Override public void onStatusUpdated() { Intent intent = new Intent(LocalPlayerActivity.this, ExpandedControlsActivity.class); startActivity(intent); remoteMediaClient.unregisterCallback(this); } }); remoteMediaClient.load(new MediaLoadRequestData.Builder() .setMediaInfo(mSelectedMedia) .setAutoplay(autoPlay) .setCurrentTime(position).build()); }
Gönderen uygulamanız bir video veya ses canlı yayını oynatırken SDK, oynatma/duraklatma düğmesi yerine otomatik olarak bir oynat/durdur düğmesi görüntüler ekleyebilirsiniz.
Temaları kullanarak görünümü ayarlamak, hangi düğmelerin gösterileceğini seçmek ve özel düğmeler eklemek için Genişletilmiş Denetleyiciyi Özelleştirme başlıklı makaleyi inceleyin.
Ses düzeyi kontrolü
Çerçeve, gönderen uygulamasının ses düzeyini otomatik olarak yönetir. Çerçeve, gönderen kullanıcı arayüzünün her zaman web alıcısı tarafından belirtilen ses düzeyini bildirmesi için gönderen ve web alıcısı uygulamalarını otomatik olarak senkronize eder.
Fiziksel düğme ses düzeyi kontrolü
Android'de, Jelly Bean veya sonraki sürümleri kullanan tüm cihazlarda varsayılan olarak web alıcısındaki Cast oturumunun ses seviyesini değiştirmek için gönderen cihazdaki fiziksel düğmeler kullanılabilir.
Jelly Bean'den önce fiziksel düğme ses düzeyi kontrolü
Şurada Web Alıcısı cihaz ses düzeyini kontrol etmek üzere fiziksel ses düzeyi tuşlarını kullanmak için:
Jelly Bean'den daha eski Android cihazlar; gönderen uygulaması,
dispatchKeyEvent
ve telefon görüşmesi yapmak için
CastContext.onDispatchVolumeKeyEventBeforeJellyBean()
:
class MyActivity : FragmentActivity() { override fun dispatchKeyEvent(event: KeyEvent): Boolean { return (CastContext.getSharedInstance(this) .onDispatchVolumeKeyEventBeforeJellyBean(event) || super.dispatchKeyEvent(event)) } }
class MyActivity extends FragmentActivity { @Override public boolean dispatchKeyEvent(KeyEvent event) { return CastContext.getSharedInstance(this) .onDispatchVolumeKeyEventBeforeJellyBean(event) || super.dispatchKeyEvent(event); } }
Bildirim ve kilit ekranına medya denetimleri ekleyin
Yalnızca Android'de, Google Cast Tasarımla İlgili Yapılacaklar Listesi bir gönderen uygulamasının
medya kontrollerini de
bildirim
ve kilitte
ekranı
Bu durumda, gönderenin yayın yaptığı ancak gönderen uygulamasının odağı olmadığı durumlar olabilir. Gönderen uygulamanın bildirimde ve kilit ekranında medya kontrolleri oluşturmasına yardımcı olmak için çerçeve MediaNotificationService
ve MediaIntentReceiver
sağlar.
MediaNotificationService
, gönderen yayın yaparken çalışır ve bir uyarı görüntüler
küçük resmi ve geçerli yayınla ilgili bilgileri içeren bildirim
bir oynatma/duraklat düğmesi ve bir durdurma düğmesi.
MediaIntentReceiver
, şuradan gelen kullanıcı işlemlerini işleyen bir BroadcastReceiver
:
bildirim.
Uygulamanız, kilit ekranından bildirim ve medya kontrolünü yapılandırabilir.
NotificationOptions
.
Uygulamanız bildirimde hangi düğmelerin gösterileceğini yapılandırabilir ve
Kullanıcı bildirime dokunduğunda hangi Activity
açılacaktır. İşlemler açıkça sağlanmazsa varsayılan değerler (MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK
ve MediaIntentReceiver.ACTION_STOP_CASTING
) kullanılır.
// Example showing 4 buttons: "rewind", "play/pause", "forward" and "stop casting". val buttonActions: MutableList<String> = ArrayList() buttonActions.add(MediaIntentReceiver.ACTION_REWIND) buttonActions.add(MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK) buttonActions.add(MediaIntentReceiver.ACTION_FORWARD) buttonActions.add(MediaIntentReceiver.ACTION_STOP_CASTING) // Showing "play/pause" and "stop casting" in the compat view of the notification. val compatButtonActionsIndices = intArrayOf(1, 3) // Builds a notification with the above actions. Each tap on the "rewind" and "forward" buttons skips 30 seconds. // Tapping on the notification opens an Activity with class VideoBrowserActivity. val notificationOptions = NotificationOptions.Builder() .setActions(buttonActions, compatButtonActionsIndices) .setSkipStepMs(30 * DateUtils.SECOND_IN_MILLIS) .setTargetActivityClassName(VideoBrowserActivity::class.java.name) .build()
// Example showing 4 buttons: "rewind", "play/pause", "forward" and "stop casting". List<String> buttonActions = new ArrayList<>(); buttonActions.add(MediaIntentReceiver.ACTION_REWIND); buttonActions.add(MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK); buttonActions.add(MediaIntentReceiver.ACTION_FORWARD); buttonActions.add(MediaIntentReceiver.ACTION_STOP_CASTING); // Showing "play/pause" and "stop casting" in the compat view of the notification. int[] compatButtonActionsIndices = new int[]{1, 3}; // Builds a notification with the above actions. Each tap on the "rewind" and "forward" buttons skips 30 seconds. // Tapping on the notification opens an Activity with class VideoBrowserActivity. NotificationOptions notificationOptions = new NotificationOptions.Builder() .setActions(buttonActions, compatButtonActionsIndices) .setSkipStepMs(30 * DateUtils.SECOND_IN_MILLIS) .setTargetActivityClassName(VideoBrowserActivity.class.getName()) .build();
Bildirim ve kilit ekranından medya denetimlerinin gösterilmesi varsayılan olarak etkindir ve CastMediaOptions.Builder
parametresinde null değeriyle setNotificationOptions
çağrılarak devre dışı bırakılabilir.
Şu anda bildirim etkinleştirildiği sürece kilit ekranı özelliği etkin durumdadır
açıldı.
// ... continue with the NotificationOptions built above val mediaOptions = CastMediaOptions.Builder() .setNotificationOptions(notificationOptions) .build() val castOptions: CastOptions = Builder() .setReceiverApplicationId(context.getString(R.string.app_id)) .setCastMediaOptions(mediaOptions) .build()
// ... continue with the NotificationOptions built above CastMediaOptions mediaOptions = new CastMediaOptions.Builder() .setNotificationOptions(notificationOptions) .build(); CastOptions castOptions = new CastOptions.Builder() .setReceiverApplicationId(context.getString(R.string.app_id)) .setCastMediaOptions(mediaOptions) .build();
Gönderen uygulamanız video veya sesli canlı yayın oynatırken SDK, bildirim kontrolünde oynatma/duraklatma düğmesi yerine otomatik olarak oynatma/durdurma düğmesi gösterir ancak kilit ekranı kontrolünde bu düğmeyi göstermez.
Not: Lollipop öncesi cihazlarda kilit ekranı kontrollerini görüntülemek için
RemoteMediaClient
, sizin adınıza otomatik olarak ses odağı isteğinde bulunacak.
Hataları işleme
Gönderen uygulamalarının tüm hata geri çağırmalarıyla ilgilenmesi ve her aşaması için en iyi yanıtı verir. Uygulama, mesajı gönderebilir veya web ile olan bağlantıyı koparabilir. Web Alıcısı.