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önderilir. Gönderen uygulaması veya Cast uygulaması gönderen üzerinde de çalışan bir uygulama anlamına gelir. 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.
- Bu çerçeve, medya içeriklerini yüklemek ve kontrol etmek için iletişim kanalını kullanır. Web Alıcısı'nda oynatma.
- Ç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ı için aşağıdaki kodu yapılandırmanız gerekiyor öğeleri oluşturun:
uses-sdk
Cast SDK'sının desteklediği minimum ve hedef Android API düzeylerini belirleyin. Şu anda minimum değer API düzeyi 23'tür, hedef ise API düzeyi 34.
<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,
Şu minimum Android SDK sürümü hedeflendiğinde Theme.AppCompat
Lollipop'tan önce gelir.
<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
OptionsProvider
ilk kullanıma hazırlamak için gereken seçenekleri sağlayacak
CastContext
singleton. 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; } }
Uygulanan OptionsProvider
öğesinin tam adını beyan etmeniz gerekir
gönderen uygulamasının AndroidManifest.xml dosyasında meta veri alanı olarak:
<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 Yayınla iletişim kutusu görüntülenir cihazlar listelenir. 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ınla düğmesi" bazen "Yayınla simgesi" olarak değiştirebilirsiniz.
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. Önce xml dosyasına bir menü seçeneği veya MediaRouteButton
eklemelisiniz
dosyanızı tanımlayan
CastButtonFactory
bunu çerçeveyle
bağlayacağım.
// 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ınla iletişim kutusu açık.
- Cast SDK'sı, 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 Buyer'ı 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()
.
Farklı oturumlar sınıfın alt sınıflarıyla temsil edilir
Session
.
Ö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 otomatik olarak
oturum aktif durumdayken anormal/ani fesih.
Oturumlar, kullanıcı hareketlerine göre otomatik olarak oluşturulur ve kısaltılır
iletişim kutusunu MediaRouter
Uygulamalar, Yayın başlatma hatalarını daha iyi anlamak için
CastContext#getCastReasonCodeForCastStatusCode(int)
oturum başlatma hatasını
CastReasonCodes
.
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 şu numarayı arayın:
CastSession#getCastDevice()
onDeviceNameChanged
geri araması sırasında.
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 kurtar
- Uygulamayı arka plana alma durumundan kurtar
- Uygulama kilitlenirse kurtar
Bu hizmet varsayılan olarak etkindir ve şuradan devre dışı bırakılabilir:
CastOptions.Builder
.
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.
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
kullanır.
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 şu kullanıcılar tarafından paylaşılması beklenir:
uygulamanızın bazı dahili bileşenleri de dahil olmak üzere
ve kullanıcı tanımlı değişkenleri kullanın. Örneğin, sürekli mini denetleyiciler ve
bildirim hizmetini kullanın.
Bu amaçla, bu örnek birden fazla
RemoteMediaClient.Listener
Medya meta verilerini ayarla
İ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. İlk kullanım
MediaInfo.Builder
medyanın meta verileriyle karşılaştırarak
MediaInfo
kullanır. Ş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());
Ayrıca, medya parçalarını kullanma.
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, ekleyebileceğiniz özel bir MiniControllerFragment sunar. göstermek istediğiniz her etkinliğin düzen dosyasının en altına mini kumanda.
<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
kapsamı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; } }
Şimdi yeni etkinliğinizi application
etiketinin içindeki uygulama manifest'inde bildirin:
<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 için, görüntülenecek düğmeleri seçin, ve özel düğmeler eklemek için Genişletilmiş Denetleyici'yi özelleştirin.
Ses düzeyi kontrolü
Çerçeve, gönderen uygulaması için ses düzeyini otomatik olarak yönetir. Çerçeve Gönderenin, gönderen ve Web Alıcı uygulamalarını otomatik olarak senkronize etmesi için, Kullanıcı arayüzü, her zaman Web Alıcısı tarafından belirtilen ses düzeyini bildirir.
Fiziksel düğme ses düzeyi kontrolü
Android'de, gönderen cihazın üzerindeki fiziksel düğmeler, varsayılan olarak Web Alıcısı'ndaki Yayın oturumunun ses düzeyi Jelly Bean veya daha yeni sürümler.
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. İlgili içeriği oluşturmak için kullanılan
çerçeve,
MediaNotificationService
ve
MediaIntentReceiver
(gönderen uygulamasının bildirim ve kilit simgesinde medya denetimleri oluşturmasına yardımcı olur)
tıklayın.
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. Eğer eylemler
doğrudan sağlanmazsa, varsayılan değerler,
MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK
ve
MediaIntentReceiver.ACTION_STOP_CASTING
kullanılacak.
// 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ında medya denetimlerini gösterme özelliği şu kullanıcı tarafından etkinleştirildi:
varsayılandır ve çağrı yaparak devre dışı bırakılabilir
setNotificationOptions
içinde boş değer olan
CastMediaOptions.Builder
.
Ş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 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 kilit ekranı denetiminde değil.
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ı.