Android uygulamalarını yayınlama özelliğini etkinleştirme

1. Genel bakış

Google Cast logosu

Bu codelab'de Google Cast uyumlu bir cihazda içerik yayınlamak için mevcut bir Android video uygulamasının nasıl değiştirileceği açıklanmaktadır.

Google Cast nedir?

Google Cast, kullanıcıların mobil cihazlardan TV'ye içerik yayınlamasına olanak tanır. Kullanıcılar daha sonra mobil cihazlarını TV'de medya oynatma için uzaktan kumanda olarak kullanabilir.

Google Cast SDK'sı, TV veya ses sistemini kontrol etmek için uygulamanızı genişletmenize olanak tanır. Cast SDK'sı, Google Cast Tasarım Listesi'ne göre gerekli kullanıcı arayüzü bileşenlerini eklemenize olanak tanır.

Google Cast Tasarım Listesi, Cast kullanıcı deneyimini desteklenen tüm platformlarda basit ve tahmin edilebilir hale getirmek amacıyla hazırlanmıştır.

Ne tür bir kampanya oluşturacağız?

Bu codelab'i tamamladığınızda Google Cast uyumlu bir cihaza video yayınlayabilecek bir Android video uygulamanız olacaktır.

Neler öğreneceksiniz?

  • Google Cast SDK'sı örnek bir video uygulamasına nasıl eklenir?
  • Google Cast cihazı seçmek için Yayınla düğmesini ekleme.
  • Yayın cihazına bağlanma ve medya alıcısı başlatma.
  • Video nasıl yayınlanır?
  • Uygulamanıza Cast mini denetleyici ekleme.
  • Medya bildirimleri ve kilit ekranı denetimleri nasıl desteklenir?
  • Genişletilmiş kumanda ekleme.
  • Tanıtım amaçlı yer paylaşımı sağlama.
  • Yayın widget'larını özelleştirme.
  • Cast Connect ile entegrasyon

Gerekenler

  • En son Android SDK.
  • Android Studio 3.2 ve üzeri sürümler
  • Android 4.1 veya sonraki bir Jelly Bean sürümüne sahip bir mobil cihaz (API düzeyi 16).
  • Mobil cihazınızı geliştirme bilgisayarınıza bağlamak için USB veri kablosu.
  • İnternet erişimiyle yapılandırılmış Chromecast veya Android TV gibi bir Google Cast cihazı.
  • HDMI girişi olan bir TV veya monitör.
  • Cast Connect entegrasyonunu test etmek için Google TV'li Chromecast gereklidir ancak Codelab'in geri kalanında isteğe bağlıdır. Böyle bir cihazınız yoksa bu eğiticinin sonuna doğru Cast Connect Desteği adımını atlayabilirsiniz.

Deneyim

  • Bunun için önce Kotlin ve Android geliştirme bilgisine sahip olmanız gerekir.
  • Ayrıca, TV izleme konusunda önceden bilgi sahibi olmanız gerekir :)

Bu eğiticiyi nasıl kullanacaksınız?

Yalnızca okuyun Okuyun ve alıştırmaları tamamlayın

Android uygulamaları oluşturma deneyiminizi nasıl değerlendirirsiniz?

Acemi Orta Yeterli

TV izleme deneyiminizi nasıl değerlendirirsiniz?

Acemi Orta Yeterli

2. Örnek kodu alın

Tüm örnek kodu bilgisayarınıza indirebilirsiniz...

ve indirilen zip dosyasının paketini açın.

3. Örnek uygulamayı çalıştırın

bir çift pusula simgesi

Öncelikle, tamamlanmış örnek uygulamanın nasıl göründüğüne bakalım. Uygulama temel bir video oynatıcıdır. Kullanıcı, listeden bir video seçebilir, ardından videoyu cihazda yerel olarak oynatabilir veya Google Cast cihazına yayınlayabilir.

İndirilen kodla aşağıdaki talimatlarda, tamamlanan örnek uygulamanın Android Studio'da nasıl açılacağı ve çalıştırılacağı açıklanmaktadır:

Karşılama ekranında Projeyi İçe Aktar veya Dosya > Yeni > Projeyi İçe Aktar... menü seçeneklerini belirleyin.

Örnek kod klasöründen klasör simgesiapp-done dizinini seçin ve Tamam'ı tıklayın.

Dosya > Android Studio "Projeyi Gradle ile Senkronize Et" düğmesi Projeyi Gradle Dosyalarıyla Senkronize Et'i tıklayın.

Android cihazınızda USB üzerinden hata ayıklamayı etkinleştirin. Android 4.2 ve daha sonraki sürümlerde, Geliştirici seçenekleri ekranı varsayılan olarak gizlidir. Numarayı görünür hale getirmek için Ayarlar > Telefon hakkında bölümüne gidin ve Derleme numarası'na yedi kez dokunun. Önceki ekrana dönün, Sistem > Gelişmiş'e gidin ve alt kısma yakın bir yerdeki Geliştirici seçenekleri'ne dokunup USB üzerinden hata ayıklama'ya dokunun.

Android cihazınızı fişe takın ve Android Studio'daki Android Studio'nun Çalıştır düğmesi, sağı gösteren yeşil bir üçgenÇalıştır düğmesini tıklayın. Yayın Videoları adlı video uygulamasının birkaç saniye sonra görünmesi gerekir.

Video uygulamasında Yayın düğmesini tıklayın ve Google Cast cihazınızı seçin.

Bir video seçin ve oynat düğmesini tıklayın.

Video, Google Cast cihazınızda oynatılmaya başlar.

Genişletilmiş kumanda gösterilir. Oynatmayı kontrol etmek için oynat/duraklat düğmesini kullanabilirsiniz.

Video listesine geri dönün.

Ekranın alt kısmında bir mini kumanda görünür. Ekranında mini mini kumandasıyla "Video Yayınlama" uygulamasını çalıştıran bir Android telefonun resmi

Alıcı üzerinde videoyu duraklatmak için mini kumandadaki duraklat düğmesini tıklayın. Videoyu tekrar oynatmaya devam etmek için mini kumandada oynat düğmesini tıklayın.

Mobil cihazın ana sayfa düğmesini tıklayın. Bildirimleri aşağı çektiğinizde Yayın oturumu için bir bildirim görürsünüz.

Telefonunuzu kilitlediğinizde, kilidi açtığınızda medya oynatmayı kontrol etmek veya yayını durdurmak için kilit ekranında bir bildirim görürsünüz.

Video uygulamasına dönün ve Google Cast cihazında yayınlamayı durdurmak için Yayınla düğmesini tıklayın.

Sık sorulan sorular

4. Başlangıç projesini hazırlama

"Video Yayınlama" uygulamasını çalıştıran bir Android telefonun resmi

İndirdiğiniz başlangıç uygulamasına, Google Cast için destek eklememiz gerekiyor. Bu codelab'de kullanacağımız bazı Google Cast terimleri şunlardır:

  • Mobil cihazda veya dizüstü bilgisayarda çalışan bir gönderen uygulaması
  • Google Cast cihazında çalışan bir alıcı uygulaması

Artık Android Studio'yu kullanarak başlangıç projesinin üzerine inşa etmeye hazırsınız:

  1. Örnek kod indirmenizden klasör simgesiapp-start dizinini seçin (karşılama ekranında Projeyi İçe Aktar'ı veya Dosya > Yeni > Projeyi İçe Aktar... menü seçeneğini belirleyin).
  2. Android Studio "Projeyi Gradle ile Senkronize Et" düğmesi Projeyi Gradle Dosyalarıyla Senkronize Et düğmesini tıklayın.
  3. Uygulamayı çalıştırmak ve kullanıcı arayüzünü keşfetmek için Android Studio'nun Çalıştır düğmesi, sağı gösteren yeşil bir üçgenÇalıştır düğmesini tıklayın.

Uygulama tasarımı

Uygulama, uzak bir web sunucusundan video listesi getirir ve kullanıcının göz atabilmesi için bir liste sağlar. Kullanıcılar bir videoyu seçerek ayrıntılarını görebilir veya mobil cihazda videoyu yerel olarak oynatabilir.

Uygulama iki ana etkinlikten oluşur: VideoBrowserActivity ve LocalPlayerActivity. Google Cast işlevini entegre etmek için Etkinlikler'in AppCompatActivity veya üst öğesinden FragmentActivity devralması gerekir. Bu sınırlama, MediaRouteButton (MediaRouter destek kitaplığında sağlanan) bir MediaRouteActionProvider olarak eklenmesi gerektiği için mevcuttur ve bu yalnızca etkinlik yukarıda belirtilen sınıflardan devralındığında işe yarar. MediaRouter destek kitaplığı, gerekli sınıfları sunan AppCompat destek kitaplığına bağlıdır.

VideoTarayıcıEtkinliği

Bu etkinlik bir Fragment (VideoBrowserFragment) içeriyor. Bu liste bir ArrayAdapter (VideoListAdapter) tarafından destekleniyor. Videoların listesi ve bunlarla ilişkili meta veriler, JSON dosyası olarak uzak bir sunucuda barındırılıyor. Bir AsyncTaskLoader (VideoItemLoader), bu JSON'yi getirir ve MediaItem nesnelerinin bir listesini oluşturmak için işler.

MediaItem nesnesi, bir videoyu ve başlığı, açıklaması, akışın URL'si, destekleyici resimlerin URL'si ve varsa ilişkili metin parçaları (altyazılar) gibi ilişkili meta verilerini modeller. MediaItem nesnesi, etkinlikler arasında iletildiği için MediaItem nesnesinin Bundle biçimine (veya tam tersi) dönüştürülmesi için yardımcı yöntemler vardır.

Yükleyici MediaItems listesini oluştururken, bu listeyi VideoListAdapter listesine iletir ve daha sonra, VideoBrowserFragment içindeki MediaItems listesini sunar. Kullanıcıya her video için kısa bir açıklama içeren video küçük resimleri listesi sunulur. Bir öğe seçildiğinde, karşılık gelen MediaItem bir Bundle öğesine dönüştürülür ve LocalPlayerActivity öğesine aktarılır.

YerelPlayer Etkinliği

Bu etkinlik, belirli bir videoyla ilgili meta verileri gösterir ve kullanıcının videoyu mobil cihazda yerel olarak oynatmasına olanak tanır.

Etkinlikte VideoView, bazı medya denetimleri ve seçilen videonun açıklamasını gösteren bir metin alanı bulunur. Oynatıcı ekranın alt kısmını kaplar ve altındaki videonun ayrıntılı açıklaması için yer bırakır. Kullanıcı videoları oynatabilir/duraklatabilir veya yerel olarak oynatma işlemini gerçekleştirebilir.

Bağımlılıklar

AppCompatActivity kullandığımız için AppCompat destek kitaplığına ihtiyacımız var. Video listesini yönetmek ve listeyle ilgili resimleri eşzamansız olarak almak için Volley kitaplığını kullanıyoruz.

Sık sorulan sorular

5. Yayınla düğmesi ekleniyor

Yayın Video uygulamasının çalıştığı bir Android telefonun en üst kısmındaki görseli; ekranın sağ üst köşesinde Yayınla düğmesi görünüyor

Cast uyumlu bir uygulama, Yayınla düğmelerinin her birinde Yayınla düğmesini görüntüler. Yayınla düğmesi tıklandığında, kullanıcının seçebileceği Yayın cihazlarının listesi görüntülenir. Kullanıcı, gönderen cihazda yerel olarak içerik oynatıyorsa, yayın cihazı seçildiğinde o yayın cihazında oynatma işlemi başlar veya devam eder. Kullanıcı, Yayın oturumu sırasında istediği zaman Yayınla düğmesini tıklayıp uygulamanızı Yayın cihazına yayınlamayı durdurabilir. Kullanıcının, Google Cast Tasarım Listesi'nde açıklandığı şekilde, uygulamanızın herhangi bir etkinliğindeyken Yayın cihazına bağlanabilmesi veya Yayın cihazının bağlantısını kesebilmesi gerekir.

Bağımlılıklar

Uygulama derlemesi.gradle dosyasını, gerekli kitaplık bağımlılıklarını içerecek şekilde güncelleyin:

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

Projenin hata olmadan oluşturulduğundan emin olmak için projeyi senkronize edin.

Başlatma

Yayın çerçevesinin, tüm Cast etkileşimlerini koordine eden genel bir tekil nesne (CastContext) vardır.

CastContext tek türünü başlatmak için gereken CastOptions değerini sağlamak üzere OptionsProvider arayüzünü uygulamanız gerekir. En önemli seçenek, Yayın cihazı keşif sonuçlarını filtrelemek ve bir Yayın oturumu başlatıldığında alıcı uygulamasını başlatmak için kullanılan alıcı uygulama kimliğidir.

Kendi Cast özellikli uygulamanızı geliştirdiğinizde, bir Cast geliştiricisi olarak kaydolmanız ve ardından uygulamanız için bir uygulama kimliği edinmeniz gerekir. Bu codelab'de örnek bir uygulama kimliği kullanacağız.

Projenin com.google.sample.cast.refplayer paketine aşağıdaki yeni CastOptionsProvider.kt dosyasını ekleyin:

package com.google.sample.cast.refplayer

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

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

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

Şimdi OptionsProvider uygulamasını AndroidManifest.xml dosyasının "application" etiketi içinde belirtin:

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

VideoBrowserActivity onCreate yöntemindeki CastContext öğesini geç başlatın:

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

private var mCastContext: CastContext? = null

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

    mCastContext = CastContext.getSharedInstance(this)
}

LocalPlayerActivity öğesine aynı başlatma mantığını ekleyin.

Yayınla düğmesi

CastContext başlatıldığına göre kullanıcının Yayın cihazı seçmesine izin vermek için Yayınla düğmesini eklememiz gerekiyor. Yayınla düğmesi, MediaRouter destek kitaplığındaki MediaRouteButton tarafından uygulanır. Etkinliğinize ekleyebileceğiniz tüm işlem simgeleri (ActionBar veya Toolbar kullanarak) gibi, önce ilgili menü öğesini menünüze eklemeniz gerekir.

res/menu/browse.xml dosyasını düzenleyin ve MediaRouteActionProvider öğesini menü öğesinin önüne ekleyin:

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

MediaRouteButton öğesinin Yayın çerçevesine bağlanması için CastButtonFactory kullanarak VideoBrowserActivity öğesinin onCreateOptionsMenu() yöntemini geçersiz kılın:

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

private var mediaRouteMenuItem: MenuItem? = null

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

LocalPlayerActivity kampanyasındaki onCreateOptionsMenu öğesini geçersiz bir şekilde geçersiz kılın.

Uygulamayı mobil cihazınızda çalıştırmak için Android Studio&#39;nun Çalıştır düğmesi, sağı gösteren yeşil bir üçgenÇalıştır düğmesini tıklayın. Uygulamanın işlem çubuğunda bir Yayınla düğmesi göreceksiniz. Bu düğmeyi tıkladığınızda, yerel ağınızdaki Yayın cihazları listelenir. Cihaz keşfi CastContext tarafından otomatik olarak yönetilir. Yayın cihazınızı seçtiğinizde örnek alıcı uygulama, Yayın cihazında yüklenir. Göz atma etkinliği ve yerel oynatıcı etkinliği arasında gezinebilirsiniz. Yayınla düğmesi durumu senkronize edilir.

Henüz medya oynatma desteği sağlamadığımız için henüz Cast cihazında video oynatamazsınız. Bağlantıyı kesmek için Yayınla düğmesini tıklayın.

6. Video içeriği yayınlanıyor

&quot;Video Yayınlama&quot; uygulamasını çalıştıran bir Android telefonun resmi

Örnek uygulamayı, Cast cihazında uzaktan video oynatacak şekilde genişleteceğiz. Bunun için Yayın çerçevesinin oluşturduğu çeşitli etkinlikleri dinlememiz gerekir.

Medya yayınlanıyor

Genel olarak, bir Yayın cihazında medya oynatmak isterseniz şunları yapmanız gerekir:

  1. Medya öğesini modelleyen bir MediaInfo nesnesi oluşturun.
  2. Yayın cihazına bağlanın ve alıcı uygulamanızı başlatın.
  3. MediaInfo nesnesini alıcınıza yükleyin ve içeriği oynatın.
  4. Medya durumunu takip edin.
  5. Kullanıcı etkileşimlerini temel alan oynatma komutlarını alıcıya gönderin.

Önceki bölümde 2. adımı tamamladık. 3. adım, Cast çerçevesiyle kolayca uygulanabilir. 1. adım, bir nesneyi başka bir nesneyle eşlemeye karşılık gelir. MediaInfo, Cast çerçevesinin anladığı bir şeydir ve MediaItem, uygulamamızın bir medya öğesine ilişkin kapsülüdür; bir MediaItem öğesini kolayca MediaInfo ile eşleyebiliriz.

LocalPlayerActivity örnek uygulaması, bu sıralamayı kullanarak yerel ve uzaktan oynatma arasında zaten ayrım yapar:

private var mLocation: PlaybackLocation? = null

enum class PlaybackLocation {
    LOCAL, REMOTE
}

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

Bu codelab'de tüm örnek oynatıcı mantığının tam olarak nasıl çalıştığını anlamanız önemli değildir. Uygulamanızın medya oynatıcısının iki oynatma konumunu benzer şekilde algılayacak şekilde değiştirilmesi gerektiğini anlamak önemlidir.

Şu anda yerel oynatıcı, yerel yayınlama durumuyla ilgili hiçbir bilgiye sahip olmadığı için her zaman yerel oynatma durumundadır. Cast çerçevesinde gerçekleşen durum geçişlerine göre kullanıcı arayüzünü güncellememiz gerekir. Örneğin, yayınlamaya başlarsak yerel oynatmayı durdurmamız ve bazı kontrolleri devre dışı bırakmamız gerekir. Benzer şekilde, bu etkinlik sırasında yayın yapmayı durdurursak yerel oynatma özelliğine geçmemiz gerekir. Bu sorunu çözmek için Cast çerçevesinin oluşturduğu çeşitli etkinlikleri dinlememiz gerekir.

Yayınlama oturumu yönetimi

Yayın çerçevesi için Yayın oturumu, bir cihaza bağlanma, başlama (veya katılma), bir alıcı uygulamasına bağlanma ve uygun durumlarda bir medya kontrol kanalı başlatma adımlarını birleştirir. Medya kontrol kanalı, Yayın çerçevesinin alıcı medya oynatıcıdan mesaj gönderip almasını sağlar.

Kullanıcı, Yayınla düğmesini kullanarak cihaz seçtiğinde Yayınla oturumu otomatik olarak başlatılır ve kullanıcı bağlantısı kesildiğinde otomatik olarak durdurulur. Ağ sorunları nedeniyle alıcı oturumuna yeniden bağlanma işlemi de SDK SDK tarafından otomatik olarak gerçekleştirilir.

LocalPlayerActivity öğesine bir SessionManagerListener ekleyelim:

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

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

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

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

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

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

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

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

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

LocalPlayerActivity etkinliğinde, Yayın cihazına bağlandığımızda veya Google Cast cihazının bağlantısı kesildiğinde, yerel oynatıcıya geçebilmemiz veya bu oynatıcıdan ayrılabilmemiz için bilgilendirilmek isteriz. Bağlantının kesintiye uğramasının nedeni yalnızca mobil cihazınızda çalışan uygulamanızın örneği değil, farklı bir mobil cihazda çalışan başka bir uygulamanızın (veya başka bir) örneği tarafından da kesintiye uğratabileceğidir.

Şu anda etkin olan oturuma SessionManager.getCurrentSession() olarak erişilebilir. Oturumlar, Cast iletişim kutularıyla kullanıcı etkileşimlerine yanıt olarak otomatik olarak oluşturulur ve silinir.

Oturum dinleyicimizi kaydetmemiz ve etkinlikte kullanacağımız bazı değişkenleri başlatmamız gerekir. LocalPlayerActivity onCreate yöntemini şu şekilde değiştir:

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

private var mCastContext: CastContext? = null
...

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

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

Medya yükleniyor

Cast SDK'sında RemoteMediaClient, alıcıda uzaktan medya oynatmayı yönetmek için bir dizi kullanışlı API sağlar. Medya oynatmayı destekleyen bir CastSession için SDK tarafından RemoteMediaClient otomatik olarak oluşturulur. Bu örnekte, CastSession örneğinde getRemoteMediaClient() yöntemi çağrılarak erişilebilir. Şu anda seçili videoyu alıcıya yüklemek için LocalPlayerActivity cihazına aşağıdaki yöntemleri ekleyin:

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

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

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

Şimdi, uzaktan oynatmayı desteklemek üzere Yayın oturumu mantığını kullanmak için çeşitli mevcut yöntemleri güncelleyin:

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

updatePlayButton yöntemi için isConnected değişkeninin değerini değiştirin:

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

Şimdi, uygulamayı mobil cihazınızda çalıştırmak için Android Studio&#39;nun Çalıştır düğmesi, sağı gösteren yeşil bir üçgenÇalıştır düğmesini tıklayın. Yayın cihazınıza bağlanıp video oynatmaya başlayın. Video, alıcıda oynatılıyor.

7. Mini kumanda

Yayın Tasarımı Kontrol Listesi'nde tüm yayın uygulamalarının kullanıcı mevcut içerik sayfasından ayrıldığında görünen bir mini kumanda kullanması gerekir. Mini kumanda, geçerli yayın oturumu için anında erişim ve görünür bir hatırlatıcı sağlar.

Google Cast video uygulamasında mini oynatıcıyı gösteren Android telefonun alt kısmı görseli

Cast SDK'sında özel bir görünüm (MiniControllerFragment) bulunur. Bu görünüm, mini kumandayı göstermek istediğiniz etkinliklerin uygulama düzeni dosyasına eklenebilir.

Aşağıdaki parça tanımını hem res/layout/player_activity.xml hem de res/layout/video_browser.xml öğesinin altına ekleyin:

<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"/>

Uygulamayı çalıştırmak ve video yayınlamak için Android Studio&#39;nun Çalıştır düğmesi, sağı gösteren yeşil bir üçgenÇalıştır düğmesini tıklayın. Oynatma işlemi alıcıda başladığında her etkinliğin alt kısmında mini kumandanın belirdiğini göreceksiniz. Mini kumandayı kullanarak uzaktan oynatmayı kontrol edebilirsiniz. Göz atma etkinliği ve yerel oynatıcı etkinliği arasında gezinirseniz mini kumandanın durumu, alıcının medya oynatma durumuyla senkronize olmalıdır.

8. Bildirim ve kilit ekranı

Google Cast tasarım kontrol listesi, bir gönderenin uygulamasının bildirim ve kilit ekranından medya kontrollerini uygulamasını gerektirir.

Bildirimler alanında medya denetimlerini gösteren bir Android telefonun resmi

Cast SDK'sı, gönderen uygulamanın bildirim ve kilit ekranı için medya kontrolleri oluşturmasına yardımcı olacak bir MediaNotificationService sağlar. Hizmet, gradle ile otomatik olarak uygulamanızın manifest dosyasında birleştirilir.

MediaNotificationService yayın sırasında arka planda çalışır. Yayında, geçerli yayın öğesiyle ilgili resim küçük resmi ve meta verileri, oynatma/duraklatma düğmesi ve durdur düğmesi de bulunan bir bildirim gösterilir.

CastContext başlatılırken CastOptions ile bildirim ve kilit ekranı kontrolleri etkinleştirilebilir. Bildirim ve kilit ekranı için medya kontrolleri varsayılan olarak etkindir. Bildirim etkin olduğu sürece kilit ekranı özelliği etkin durumdadır.

CastOptionsProvider öğesini düzenleyin ve getCastOptions uygulamasını bu kodla eşleşecek şekilde değiştirin:

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

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

Uygulamayı mobil cihazınızda çalıştırmak için Android Studio&#39;nun Çalıştır düğmesi, sağı gösteren yeşil bir üçgenÇalıştır düğmesini tıklayın. Bir video yayınlayın ve örnek uygulamadan ayrılın. Alıcıda oynatılan video için bir bildirim olmalıdır. Mobil cihazınızı kilitlediğinizde kilit ekranında da yayın cihazında medya oynatma kontrolleri gösterilir.

Kilit ekranında medya denetimlerini gösteren bir Android telefonun resmi

9. Tanıtım amaçlı yer paylaşımı

Google Cast tasarım kontrol listesi, gönderen uygulamanın artık yayınla özelliğini desteklediğini ve ayrıca Google Cast'i yeni kullanmaya başlayan kullanıcılara yardımcı olmak için mevcut bir kullanıcıya Yayınla düğmesini tanıtmasını gerektirir.

Google Cast Video Android uygulamasındaki Yayınla düğmesinin etrafında tanıtım amaçlı Yayın yer paylaşımının gösterildiği görsel

Cast SDK'sı, özel bir görünüm (IntroductoryOverlay) sağlar. Bu görünüm, yayınla düğmesi kullanıcılara ilk kez gösterildiğinde yayın düğmesini vurgulamak için kullanılabilir. VideoBrowserActivity alanına şu kodu ekleyin:

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

private var mIntroductoryOverlay: IntroductoryOverlay? = null

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

Şimdi, bir CastStateListener ekleyin ve yayın yöntemi kullanılabilir olduğunda showIntroductoryOverlay yöntemini çağırarak onCreate yöntemini değiştirin ve onResume ile onPause yöntemlerini aşağıdaki gibi geçersiz kılın:

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

private var mCastStateListener: CastStateListener? = null

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

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

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

Uygulama verilerini temizleyin veya uygulamayı cihazınızdan kaldırın. Ardından, uygulamayı mobil cihazınızda çalıştırmak için Android Studio&#39;nun Çalıştır düğmesi, sağı gösteren yeşil bir üçgenÇalıştır düğmesini tıklayın. Tanıtım yer paylaşımını göreceksiniz (yer paylaşımı gösterilmiyorsa uygulama verilerini temizleyin).

10. Genişletilmiş kumanda

Google Cast tasarım kontrol listesi, bir gönderen uygulamasının, yayınlanmakta olan medya için genişletilmiş denetleyici sağlamasını gerektirir. Genişletilmiş kumanda, mini kumandanın tam ekran sürümüdür.

Üzerinde genişletilmiş kumanda bulunan bir Android telefonda oynayan bir videonun görseli

Cast SDK'sı, ExpandedControllerActivity adlı genişletilmiş kumanda için bir widget sağlar. Bu, bir Yayınla düğmesi eklemek için alt sınıfa geçmeniz gereken soyut bir sınıftır.

Öncelikle, genişletilmiş kumandanın Yayın düğmesini sağlaması için expanded_controller.xml adlı yeni bir menü kaynağı dosyası oluşturun:

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

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

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

</menu>

com.google.sample.cast.refplayer paketinde yeni bir expandedcontrols paketi oluşturun. Ardından com.google.sample.cast.refplayer.expandedcontrols paketinde ExpandedControlsActivity.kt adlı yeni bir dosya oluşturun.

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

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

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

Şimdi OPTIONS_PROVIDER_CLASS_NAME öğesinin üzerindeki application etiketinin AndroidManifest.xml bölümünde ExpandedControlsActivity öğesini bildirin:

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

Hedef etkinliği ExpandedControlsActivity olarak ayarlamak için CastOptionsProvider öğesini düzenleyin ve NotificationOptions ve CastMediaOptions ayarlarını değiştirin:

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

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

Uzak medya yüklendiğinde ExpandedControlsActivity öğesini görüntülemek için LocalPlayerActivity loadRemoteMedia yöntemini güncelleyin:

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

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

Uygulamayı mobil cihazınızda çalıştırmak ve video yayınlamak için Android Studio&#39;nun Çalıştır düğmesi, sağı gösteren yeşil bir üçgenÇalıştır düğmesini tıklayın. Genişletilmiş kumandayı göreceksiniz. Video listesine geri dönün ve mini kumandayı tıkladığınızda genişletilmiş kumanda tekrar yüklenir. Bildirimi görmek için uygulamadan ayrılın. Genişletilmiş kumandayı yüklemek için bildirim resmini tıklayın.

11. Cast Connect desteği ekleme

Cast Connect kitaplığı, mevcut gönderen uygulamalarının Cast protokolü üzerinden Android TV uygulamalarıyla iletişim kurmasına olanak tanır. Cast Connect, Android yayın alıcınız gibi davranan Cast altyapısına dayanır.

Bağımlılıklar

Not: Cast Connect'i uygulamak için play-services-cast-framework, 19.0.0 veya daha yüksek bir değer olmalıdır.

Başlatma Seçenekleri

Android Alıcısı olarak da adlandırılan Android TV uygulamasını başlatmak için LaunchOptions nesnesinde setAndroidReceiverCompatible işaretini true olarak ayarlamamız gerekir. Bu LaunchOptions nesnesi, alıcının nasıl başlatılacağını ve CastOptionsProvider sınıfının döndürdüğü CastOptions öğesine iletileceğini belirtir. Yukarıda belirtilen işaret false değerine ayarlanırsa Cast Geliştirici Konsolu'nda tanımlı Uygulama Kimliği için web alıcısı başlatılır.

CastOptionsProvider.kt dosyasında, getCastOptions yöntemine aşağıdakileri ekleyin:

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

Başlatma Kimlik Bilgileri

Gönderen tarafta, oturuma kimlerin katılacağını temsil etmek için CredentialsData değerini belirtebilirsiniz. credentials, ATV uygulamanız tarafından anlaşılabildiği sürece kullanıcı tarafından tanımlanabilen bir dizedir. CredentialsData yalnızca Android TV uygulamanıza lansman veya katılma sırasında iletilir. Bağlıyken bu ayarı tekrar yaparsanız Android TV uygulamanıza iletilmez.

Lansman Kimlik Bilgilerini ayarlamak için CredentialsData parametresinin tanımlanması ve LaunchOptions nesnesine aktarılması gerekir. Aşağıdaki kodu CastOptionsProvider.kt dosyanızdaki getCastOptions yöntemine ekleyin:

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

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

Yük İsteğinde Kimlik Bilgilerini Ayarla

Web Alıcı uygulamanız ve Android TV uygulamanız credentials uygulamasını farklı şekilde işliyorsa her biri için ayrı bir credentials tanımlamanız gerekebilir. Bunun için LocalPlayerActivity.kt dosyanıza aşağıdaki loadRemoteMedia işlevini ekleyin:

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

SDK, alıcınızın yayın yaptığı alıcıya bağlı olarak mevcut oturum için kullanılacak kimlik bilgilerini otomatik olarak işler.

Cast Connect testi

Google TV'li Chromecast'e Android TV APK'sını yükleme adımları

  1. Android TV cihazınızın IP adresini bulun. Bu özellik genellikle Ayarlar > Ağ ve İnternet > (Cihazınızın bağlı olduğu ağ adı) bölümünde kullanılabilir. Sağ tarafta ayrıntıları ve cihazınızın ağdaki IP'sini gösterir.
  2. Terminali kullanarak ADB üzerinden bağlanmak için cihazınızın IP adresini kullanın:
$ adb connect <device_ip_address>:5555
  1. Terminal pencerenizden, bu codelab'in başında indirdiğiniz codelab örneklerinin üst düzey klasörüne gidin. Örneğin:
$ cd Desktop/android_codelab_src
  1. Aşağıdaki kodu çalıştırarak bu klasördeki .apk dosyasını Android TV'nize yükleyin:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. Artık Android TV cihazınızdaki Uygulamalarınız menüsünde Yayın Videoları adıyla bir uygulama görebilirsiniz.
  2. Android Studio projenize dönün ve gönderen uygulamasını fiziksel mobil cihazınıza yükleyip çalıştırmak için Çalıştır düğmesini tıklayın. Sağ üst köşedeki yayınla simgesini tıklayın ve mevcut seçenekler arasından Android TV cihazınızı seçin. Artık Android TV cihazınızda Android TV uygulamasını başlatmış olmanız ve bir video oynatmanız, Android TV uzaktan kumandanızı kullanarak video oynatmayı kontrol edebilmenizi sağlar.

12. Yayın widget'larını özelleştirme

Renkleri ayarlayarak, düğmelerin, metnin ve küçük resmin görünümünü ayarlayarak ve görüntülenecek düğme türlerini seçerek Yayınlama widget'larını özelleştirebilirsiniz.

Şunu güncelle: res/values/styles_castvideo.xml

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

Aşağıdaki özel temaları bildirin:

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

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

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

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

13. Tebrikler

Artık Android'de Yayın SDK widget'larını kullanarak video uygulamalarını Cast'i nasıl etkinleştireceğinizi biliyorsunuz.

Daha fazla ayrıntı için Android Gönderen geliştirici kılavuzuna bakın.