Android TV Alıcınıza Temel Özellikler Ekleme

Bu sayfada kod snippet'leri ve Android TV Alıcısı uygulamasını özelleştirmek için kullanılabilecek özelliklerle ilgili açıklamalar yer almaktadır.

Kitaplıkları yapılandırma

Cast Connect API'lerini Android TV uygulamanızda kullanılabilir hale getirmek için:

Android
  1. Uygulama modülü dizininizin içindeki build.gradle dosyasını açın.
  2. google() öğesinin listelenen repositories listesine eklendiğini doğrulayın.
      repositories {
        google()
      }
  3. Uygulamanız için hedef cihaz türünüze bağlı olarak, bağımlıların kitaplıklarının en son sürümlerini ekleyin:
    • Android Alıcı uygulaması için:
        dependencies {
          implementation 'com.google.android.gms:play-services-cast-tv:21.0.0'
          implementation 'com.google.android.gms:play-services-cast:21.3.0'
        }
    • Android Gönderen uygulaması için:
        dependencies {
          implementation 'com.google.android.gms:play-services-cast:21.0.0'
          implementation 'com.google.android.gms:play-services-cast-framework:21.3.0'
        }
    Hizmetler her güncellendiğinde bu sürüm numarasını güncellediğinizden emin olun.
  4. Değişiklikleri kaydedin ve araç çubuğunda Sync Project with Gradle Files simgesini tıklayın.
iOS
  1. Podfile hedeflemesinin google-cast-sdk 4.7.0 veya sonraki bir sürümü hedeflediğinden emin olun
  2. iOS 12 veya sonraki bir sürümü hedefleyin. Daha fazla bilgi için Sürüm Notları'na bakın.
      platform: ios, '12'
    
      def target_pods
         pod 'google-cast-sdk', '~>4.7.0'
      end
Web
  1. Chromium tarayıcı M87 veya sonraki bir sürüm gerekir.
  2. Web Gönderen API kitaplığını projenize ekleyin
      <script src="//www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>

AndroidX gereksinimi

Google Play Hizmetleri'nin yeni sürümlerinde bir uygulamanın androidx ad alanını kullanacak şekilde güncellenmesi gerekir. AndroidX'e taşıma talimatlarını uygulayın.

Android TV uygulaması: Ön koşullar

Android TV uygulamanızda Cast Connect'i desteklemek için bir medya oturumundan etkinlik oluşturmanız ve desteklemeniz gerekir. Medya oturumunuz tarafından sağlanan veriler, medya durumunuzla ilgili temel bilgileri (ör. konum, oynatma durumu vb.) sağlar. Ayrıca, medya oturumunuz Cast Connect kitaplığı tarafından, bir gönderenden gelen duraklatma gibi belirli mesajları aldığında sinyal vermek için kullanılır.

Medya oturumu ve medya oturumunu başlatma hakkında daha fazla bilgi için medya oturumuyla çalışma kılavuzuna bakın.

Medya oturumu yaşam döngüsü

Uygulamanız oynatma başladığında bir medya oturumu oluşturmalı ve artık kontrol edilemediğinde yayınlamalıdır. Örneğin, uygulamanız bir video uygulamasıysa kullanıcı oynatma etkinliğinden çıktığında, diğer içeriğe göz atmak için "geri"yi seçerek veya uygulamanın arka planını seçerek oturumu yayınlamanız gerekir. Uygulamanız bir müzik uygulamasıysa uygulamanız artık medya oynatmadığında yayınlamalısınız.

Oturum durumu güncelleniyor

Medya oturumunuzdaki veriler, oynatıcınızın durumuyla ilgili güncel bilgiler içermelidir. Örneğin, oynatma duraklatıldığında, oynatma durumunu ve desteklenen işlemleri güncellemeniz gerekir. Aşağıdaki tablolarda, güncel kalmaktan sorumlu olduğunuz durumlar listelenmiştir.

MediaMetaCompat

Meta Veri Alanı Açıklama
METADATA_KEY_TITLE (zorunlu) Medya başlığı.
METADATA_KEY_DISPLAY_SUBTITLE Altyazı.
METADATA_KEY_DISPLAY_ICON_URI Simge URL'si.
METADATA_KEY_DURATION (zorunlu) Medya süresi.
METADATA_KEY_MEDIA_URI Content ID.
METADATA_KEY_ARTIST Sanatçı.
METADATA_KEY_ALBUM Albüm.

PlayStateCompat

Gerekli Yöntem Açıklama
setActions() Desteklenen medya komutlarını ayarlar.
setState() Oynatma durumunu ve mevcut konumu ayarlayın.

MediaSessionCompat

Gerekli Yöntem Açıklama
setTekrarMode() Tekrar modunu ayarlar.
setMixedMode() Karıştırma modunu ayarlar.
setMeta() Medya meta verilerini ayarlar.
setPlayState() Oynatma durumunu ayarlar.
Kotlin
private fun updateMediaSession() {
    val metadata = MediaMetadataCompat.Builder()
         .putString(MediaMetadataCompat.METADATA_KEY_TITLE, "title")
         .putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, "subtitle")
         .putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI, mMovie.getCardImageUrl())
         .build()

    val playbackState = PlaybackStateCompat.Builder()
         .setState(
             PlaybackStateCompat.STATE_PLAYING,
             player.getPosition(),
             player.getPlaybackSpeed(),
             System.currentTimeMillis()
        )
         .build()

    mediaSession.setMetadata(metadata)
    mediaSession.setPlaybackState(playbackState)
}
Java
private void updateMediaSession() {
  MediaMetadataCompat metadata =
      new MediaMetadataCompat.Builder()
          .putString(MediaMetadataCompat.METADATA_KEY_TITLE, "title")
          .putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, "subtitle")
          .putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI,mMovie.getCardImageUrl())
          .build();

  PlaybackStateCompat playbackState =
      new PlaybackStateCompat.Builder()
          .setState(
               PlaybackStateCompat.STATE_PLAYING,
               player.getPosition(),
               player.getPlaybackSpeed(),
               System.currentTimeMillis())
          .build();

  mediaSession.setMetadata(metadata);
  mediaSession.setPlaybackState(playbackState);
}

Taşıma denetimini kullanma

Uygulamanız medya oturumu taşıma kontrolü geri çağırmasını uygulamalıdır. Aşağıdaki tabloda, hangi taşıma kontrolü işlemlerinin işlenmesi gerektiği gösterilmektedir:

MediaSessionCompat.Callback

İşlemler Açıklama
onPlay() Devam ettir
onPause() Duraklat
onSeekTo() Bir konuma git
onStop() Geçerli medyayı durdur
Kotlin
class MyMediaSessionCallback : MediaSessionCompat.Callback() {
  override fun onPause() {
    // Pause the player and update the play state.
    ...
  }

  override fun onPlay() {
    // Resume the player and update the play state.
    ...
  }

  override fun onSeekTo (long pos) {
    // Seek and update the play state.
    ...
  }
  ...
}

mediaSession.setCallback( MyMediaSessionCallback() );
Java
public MyMediaSessionCallback extends MediaSessionCompat.Callback {
  public void onPause() {
    // Pause the player and update the play state.
    ...
  }

  public void onPlay() {
    // Resume the player and update the play state.
    ...
  }

  public void onSeekTo (long pos) {
    // Seek and update the play state.
    ...
  }
  ...
}

mediaSession.setCallback(new MyMediaSessionCallback());

Yayın desteğini yapılandırma

Bir gönderen uygulaması tarafından başlatma isteği gönderildiğinde, uygulama ad alanını kullanarak bir niyet oluşturulur. Uygulamanız, TV uygulaması başlatıldığında CastReceiverContext nesnesinin örneğini yönetmekten ve bu örneği oluşturmaktan sorumludur. TV uygulaması çalışırken Yayın ile etkileşimde bulunmak için CastReceiverContext nesnesi gerekir. Bu nesne, TV uygulamanızın bağlı gönderenlerden gelen Cast medya mesajlarını kabul etmesini sağlar.

Android TV kurulumu

Başlatma amacı filtresi ekleme

Gönderen uygulamanızdan başlatma amacını işlemek istediğiniz etkinliğe yeni bir intent filtresi ekleyin:

<activity android:name="com.example.activity">
  <intent-filter>
      <action android:name="com.google.android.gms.cast.tv.action.LAUNCH" />
      <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
</activity>

Alıcı seçenekleri sağlayıcısı belirtin

CastReceiverOptions hizmetini sağlamak için bir ReceiverOptionsProvider uygulamanız gerekir:

Kotlin
class MyReceiverOptionsProvider : ReceiverOptionsProvider {
  override fun getOptions(context: Context?): CastReceiverOptions {
    return CastReceiverOptions.Builder(context)
          .setStatusText("My App")
          .build()
    }
}
Java
public class MyReceiverOptionsProvider implements ReceiverOptionsProvider {
  @Override
  public CastReceiverOptions getOptions(Context context) {
    return new CastReceiverOptions.Builder(context)
        .setStatusText("My App")
        .build();
  }
}

Ardından, AndroidManifest içinde seçenekler sağlayıcısını belirtin:

 <meta-data
    android:name="com.google.android.gms.cast.tv.RECEIVER_OPTIONS_PROVIDER_CLASS_NAME"
    android:value="com.example.mysimpleatvapplication.MyReceiverOptionsProvider" />

ReceiverOptionsProvider, CastReceiverContext başlatıldığında CastReceiverOptions öğesini sağlamak için kullanılır.

Yayın alıcısı bağlamı

Uygulamanız oluşturulduğunda CastReceiverContext öğesini başlatın:

Kotlin
override fun onCreate() {
  CastReceiverContext.initInstance(this)

  ...
}
Java
@Override
public void onCreate() {
  CastReceiverContext.initInstance(this);

  ...
}

Uygulamanız ön plana geçtiğinde CastReceiverContext öğesini başlatın:

Kotlin
CastReceiverContext.getInstance().start()
Java
CastReceiverContext.getInstance().start();

Uygulama, video uygulamaları veya arka planda oynatmayı desteklemeyen uygulamalar için arka plana geçtikten sonra CastReceiverContext üzerinden stop() numaralı telefonu arayın:

Kotlin
// Player has stopped.
CastReceiverContext.getInstance().stop()
Java
// Player has stopped.
CastReceiverContext.getInstance().stop();

Ayrıca, uygulamanız arka planda oynatmayı destekliyorsa arka planda oynatmayı durdurduğunda CastReceiverContext üzerinden stop() işlevini çağırın.

Özellikle yerel uygulamanızda birden fazla etkinlik varsa CastReceiverContext.start() ve CastReceiverContext.stop() çağrılarını yönetmek için androidx.lifecycle kitaplığından LifecycleObserver'ı kullanmanızı önemle tavsiye ederiz. Bu işlem, farklı etkinliklerden start() ve stop() numaralı telefonu aradığınızda yarış koşullarını önler.

Kotlin
// Create a LifecycleObserver class.
class MyLifecycleObserver : DefaultLifecycleObserver {
  override fun onStart(owner: LifecycleOwner) {
    // App prepares to enter foreground.
    CastReceiverContext.getInstance().start()
  }

  override fun onStop(owner: LifecycleOwner) {
    // App has moved to the background or has terminated.
    CastReceiverContext.getInstance().stop()
  }
}

// Add the observer when your application is being created.
class MyApplication : Application() {
  fun onCreate() {
    super.onCreate()

    // Initialize CastReceiverContext.
    CastReceiverContext.initInstance(this /* android.content.Context */)

    // Register LifecycleObserver
    ProcessLifecycleOwner.get().lifecycle.addObserver(
        MyLifecycleObserver())
  }
}
Java
// Create a LifecycleObserver class.
public class MyLifecycleObserver implements DefaultLifecycleObserver {
  @Override
  public void onStart(LifecycleOwner owner) {
    // App prepares to enter foreground.
    CastReceiverContext.getInstance().start();
  }

  @Override
  public void onStop(LifecycleOwner owner) {
    // App has moved to the background or has terminated.
    CastReceiverContext.getInstance().stop();
  }
}

// Add the observer when your application is being created.
public class MyApplication extends Application {
  @Override
  public void onCreate() {
    super.onCreate();

    // Initialize CastReceiverContext.
    CastReceiverContext.initInstance(this /* android.content.Context */);

    // Register LifecycleObserver
    ProcessLifecycleOwner.get().getLifecycle().addObserver(
        new MyLifecycleObserver());
  }
}
// In AndroidManifest.xml set MyApplication as the application class
<application
    ...
    android:name=".MyApplication">

MediaSession'ı MediaManager'a bağlama

Bir MediaSession oluşturduğunuzda, komutların nereye gönderileceğini ve medya oynatma durumunu nereden alacağını bilebilmesi için mevcut MediaSession jetonunu CastReceiverContext'e de sağlamanız gerekir:

Kotlin
val mediaManager: MediaManager = receiverContext.getMediaManager()
mediaManager.setSessionCompatToken(currentMediaSession.getSessionToken())
Java
MediaManager mediaManager = receiverContext.getMediaManager();
mediaManager.setSessionCompatToken(currentMediaSession.getSessionToken());

Etkin olmayan oynatma nedeniyle MediaSession cihazınızı serbest bıraktığınızda MediaManager öğesinde boş bir jeton ayarlamanız gerekir:

Kotlin
myPlayer.stop()
mediaSession.release()
mediaManager.setSessionCompatToken(null)
Java
myPlayer.stop();
mediaSession.release();
mediaManager.setSessionCompatToken(null);

Uygulamanız arka plandayken medya oynatmayı destekliyorsa, uygulamanız arka plana gönderildiğinde CastReceiverContext.stop() yerine yalnızca arka planda uygulamanızın bir medyayı oynatması gerekir. Örneğin:

Kotlin
class MyLifecycleObserver : DefaultLifecycleObserver {
  ...
  // App has moved to the background.
  override fun onPause(owner: LifecycleOwner) {
    mIsBackground = true
    myStopCastReceiverContextIfNeeded()
  }
}

// Stop playback on the player.
private fun myStopPlayback() {
  myPlayer.stop()

  myStopCastReceiverContextIfNeeded()
}

// Stop the CastReceiverContext when both the player has
// stopped and the app has moved to the background.
private fun myStopCastReceiverContextIfNeeded() {
  if (mIsBackground && myPlayer.isStopped()) {
    CastReceiverContext.getInstance().stop()
  }
}
Java
public class MyLifecycleObserver implements DefaultLifecycleObserver {
  ...
  // App has moved to the background.
  @Override
  public void onPause(LifecycleOwner owner) {
    mIsBackground = true;

    myStopCastReceiverContextIfNeeded();
  }
}

// Stop playback on the player.
private void myStopPlayback() {
  myPlayer.stop();

  myStopCastReceiverContextIfNeeded();
}

// Stop the CastReceiverContext when both the player has
// stopped and the app has moved to the background.
private void myStopCastReceiverContextIfNeeded() {
  if (mIsBackground && myPlayer.isStopped()) {
    CastReceiverContext.getInstance().stop();
  }
}

Cast Connect ile Exo Player'ı kullanma

Exoplayer kullanıyorsanız değişiklikleri ve manuel değişiklikleri izlemek yerine, oturumu ve ilgili tüm bilgileri otomatik olarak korumak için MediaSessionConnector kullanabilirsiniz.

MediaSessionConnector.MediaButtonEventHandler, MediaButton etkinliklerini yönetmek için kullanılabilir. Bu etkinlikler, varsayılan olarak MediaSessionCompat.Callback tarafından işlenecek. setMediaButtonEventHandler(MediaButtonEventHandler).

Uygulamanıza MediaSessionConnector entegre etmek için aşağıdakileri oynatıcı etkinliği sınıfınıza veya medya oturumunuzu yönettiğiniz herhangi bir yere ekleyin:

Kotlin
class PlayerActivity : Activity() {
  private var mMediaSession: MediaSessionCompat? = null
  private var mMediaSessionConnector: MediaSessionConnector? = null
  private var mMediaManager: MediaManager? = null

  override fun onCreate(savedInstanceState: Bundle?) {
    ...
    mMediaSession = MediaSessionCompat(this, LOG_TAG)
    mMediaSessionConnector = MediaSessionConnector(mMediaSession!!)
    ...
  }

  override fun onStart() {
    ...
    mMediaManager = receiverContext.getMediaManager()
    mMediaManager!!.setSessionCompatToken(currentMediaSession.getSessionToken())
    mMediaSessionConnector!!.setPlayer(mExoPlayer)
    mMediaSessionConnector!!.setMediaMetadataProvider(mMediaMetadataProvider)
    mMediaSession!!.isActive = true
    ...
  }

  override fun onStop() {
    ...
    mMediaSessionConnector!!.setPlayer(null)
    mMediaSession!!.release()
    mMediaManager!!.setSessionCompatToken(null)
    ...
  }
}
Java
public class PlayerActivity extends Activity {
  private MediaSessionCompat mMediaSession;
  private MediaSessionConnector mMediaSessionConnector;
  private MediaManager mMediaManager;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    ...
    mMediaSession = new MediaSessionCompat(this, LOG_TAG);
    mMediaSessionConnector = new MediaSessionConnector(mMediaSession);
    ...
  }

  @Override
  protected void onStart() {
    ...
    mMediaManager = receiverContext.getMediaManager();
    mMediaManager.setSessionCompatToken(currentMediaSession.getSessionToken());

    mMediaSessionConnector.setPlayer(mExoPlayer);
    mMediaSessionConnector.setMediaMetadataProvider(mMediaMetadataProvider);
    mMediaSession.setActive(true);
    ...
  }

  @Override
  protected void onStop() {
    ...
    mMediaSessionConnector.setPlayer(null);
    mMediaSession.release();
    mMediaManager.setSessionCompatToken(null);
    ...
  }
}

Gönderen uygulaması kurulumu

Cast Connect desteğini etkinleştirin

Gönderen uygulamanızı Cast Connect desteğiyle güncelledikten sonra, LaunchOptions üzerindeki androidReceiverCompatible işaretini true olarak ayarlayarak uygulamanın hazır olduğunu belirtebilirsiniz.

Android

play-services-cast-framework 19.0.0 veya daha yeni bir sürüm gerekir.

androidReceiverCompatible bayrağı LaunchOptions içinde ayarlanır (CastOptions öğesinin bir parçasıdır):

Kotlin
class CastOptionsProvider : OptionsProvider {
  override fun getCastOptions(context: Context?): CastOptions {
    val launchOptions: LaunchOptions = Builder()
          .setAndroidReceiverCompatible(true)
          .build()
    return CastOptions.Builder()
          .setLaunchOptions(launchOptions)
          ...
          .build()
    }
}
Java
public class CastOptionsProvider implements OptionsProvider {
  @Override
  public CastOptions getCastOptions(Context context) {
    LaunchOptions launchOptions = new LaunchOptions.Builder()
              .setAndroidReceiverCompatible(true)
              .build();
    return new CastOptions.Builder()
        .setLaunchOptions(launchOptions)
        ...
        .build();
  }
}
iOS

google-cast-sdk v4.4.8 veya daha yeni bir sürüm gerekir.

androidReceiverCompatible bayrağı GCKLaunchOptions içinde ayarlanır (GCKCastOptions öğesinin bir parçasıdır):

let options = GCKCastOptions(discoveryCriteria: GCKDiscoveryCriteria(applicationID: kReceiverAppID))
...
let launchOptions = GCKLaunchOptions()
launchOptions.androidReceiverCompatible = true
options.launchOptions = launchOptions
GCKCastContext.setSharedInstanceWith(options)
Web

Chromium tarayıcı sürümü M87 veya sonraki bir sürüm gerektirir.

const context = cast.framework.CastContext.getInstance();
const castOptions = new cast.framework.CastOptions();
castOptions.receiverApplicationId = kReceiverAppID;
castOptions.androidReceiverCompatible = true;
context.setOptions(castOptions);

Cast Developer Console kurulumu

Android TV uygulamasını yapılandırma

Android TV uygulamanızın paket adını, Cast Uygulama Kimliğinizle ilişkilendirmek için Yayın Geliştirici Konsolu'na ekleyin.

Geliştirici cihazlarını kaydetme

Geliştirme için kullanacağınız Android TV cihazının seri numarasını Cast Developer Console'a kaydedin.

Cast Connect, güvenlik nedeniyle yalnızca Google Play Store'dan yüklenen uygulamalarda çalışır.

Yayın veya Android TV cihazını Cast geliştirme işlemi için kaydetme hakkında daha fazla bilgi edinmek isterseniz kayıt sayfasına bakın.

Medya yükleniyor

Derin bağlantı desteğini Android TV uygulamanızda zaten uyguladıysanız Android TV Manifest'inizde yapılandırılmış benzer bir tanım olur:

<activity android:name="com.example.activity">
  <intent-filter>
     <action android:name="android.intent.action.VIEW" />
     <category android:name="android.intent.category.DEFAULT" />
     <data android:scheme="https"/>
     <data android:host="www.example.com"/>
     <data android:pathPattern=".*"/>
  </intent-filter>
</activity>

Gönderen üzerinde varlığa göre yükle

Gönderenlerde, yükleme isteğinin medya bilgilerindeki entity değerini ayarlayarak derin bağlantıyı iletebilirsiniz:

Kotlin
val mediaToLoad = MediaInfo.Builder("some-id")
    .setEntity("https://example.com/watch/some-id")
    ...
    .build()
val loadRequest = MediaLoadRequestData.Builder()
    .setMediaInfo(mediaToLoad)
    .setCredentials("user-credentials")
    ...
    .build()
remoteMediaClient.load(loadRequest)
Android
Java
MediaInfo mediaToLoad =
    new MediaInfo.Builder("some-id")
        .setEntity("https://example.com/watch/some-id")
        ...
        .build();
MediaLoadRequestData loadRequest =
    new MediaLoadRequestData.Builder()
        .setMediaInfo(mediaToLoad)
        .setCredentials("user-credentials")
        ...
        .build();
remoteMediaClient.load(loadRequest);
iOS
let mediaInfoBuilder = GCKMediaInformationBuilder(entity: "https://example.com/watch/some-id")
...
mediaInformation = mediaInfoBuilder.build()

let mediaLoadRequestDataBuilder = GCKMediaLoadRequestDataBuilder()
mediaLoadRequestDataBuilder.mediaInformation = mediaInformation
mediaLoadRequestDataBuilder.credentials = "user-credentials"
...
let mediaLoadRequestData = mediaLoadRequestDataBuilder.build()

remoteMediaClient?.loadMedia(with: mediaLoadRequestData)
Web

Chromium tarayıcı sürümü M87 veya sonraki bir sürüm gerektirir.

let mediaInfo = new chrome.cast.media.MediaInfo('some-id"', 'video/mp4');
mediaInfo.entity = 'https://example.com/watch/some-id';
...

let request = new chrome.cast.media.LoadRequest(mediaInfo);
request.credentials = 'user-credentials';
...

cast.framework.CastContext.getInstance().getCurrentSession().loadMedia(request);

Yükleme komutu, derin bağlantınız ve geliştirici konsolunda tanımladığınız paket adı ile bir intent aracılığıyla gönderilir.

Gönderen için ATV kimlik bilgileri ayarlanıyor

Web Alıcı uygulamanız ve Android TV uygulamanız farklı derin bağlantıları ve credentials'yi destekliyor olabilir (örneğin, kimlik doğrulamasını iki platformda farklı bir şekilde yönetiyorsanız). Bu sorunu çözmek üzere Android TV için alternatif entity ve credentials sağlayabilirsiniz:

Android
Kotlin
val mediaToLoad = MediaInfo.Builder("some-id")
        .setEntity("https://example.com/watch/some-id")
        .setAtvEntity("myscheme://example.com/atv/some-id")
        ...
        .build()
val loadRequest = MediaLoadRequestData.Builder()
        .setMediaInfo(mediaToLoad)
        .setCredentials("user-credentials")
        .setAtvCredentials("atv-user-credentials")
        ...
        .build()
remoteMediaClient.load(loadRequest)
Java
MediaInfo mediaToLoad =
    new MediaInfo.Builder("some-id")
        .setEntity("https://example.com/watch/some-id")
        .setAtvEntity("myscheme://example.com/atv/some-id")
        ...
        .build();
MediaLoadRequestData loadRequest =
    new MediaLoadRequestData.Builder()
        .setMediaInfo(mediaToLoad)
        .setCredentials("user-credentials")
        .setAtvCredentials("atv-user-credentials")
        ...
        .build();
remoteMediaClient.load(loadRequest);
iOS
let mediaInfoBuilder = GCKMediaInformationBuilder(entity: "https://example.com/watch/some-id")
mediaInfoBuilder.atvEntity = "myscheme://example.com/atv/some-id"
...
mediaInformation = mediaInfoBuilder.build()

let mediaLoadRequestDataBuilder = GCKMediaLoadRequestDataBuilder()
mediaLoadRequestDataBuilder.mediaInformation = mediaInformation
mediaLoadRequestDataBuilder.credentials = "user-credentials"
mediaLoadRequestDataBuilder.atvCredentials = "atv-user-credentials"
...
let mediaLoadRequestData = mediaLoadRequestDataBuilder.build()

remoteMediaClient?.loadMedia(with: mediaLoadRequestData)
Web

Chromium tarayıcı sürümü M87 veya sonraki bir sürüm gerektirir.

let mediaInfo = new chrome.cast.media.MediaInfo('some-id"', 'video/mp4');
mediaInfo.entity = 'https://example.com/watch/some-id';
mediaInfo.atvEntity = 'myscheme://example.com/atv/some-id';
...

let request = new chrome.cast.media.LoadRequest(mediaInfo);
request.credentials = 'user-credentials';
request.atvCredentials = 'atv-user-credentials';
...

cast.framework.CastContext.getInstance().getCurrentSession().loadMedia(request);

Web Alıcısı uygulaması başlatılırsa yükleme isteğinde entity ve credentials kullanılır. Ancak Android TV uygulamanız kullanıma sunulduysa SDK, entity ve credentials değerlerini atvEntity ve atvCredentials değerlerinizle geçersiz kılar (belirtilirse).

Content ID veya MediaQueueData tarafından yükleniyor

entity veya atvEntity kullanmıyorsanız ve Medya Bilgilerinizde Content ID ya da İçerik URL'si kullanıyorsanız veya daha ayrıntılı bir Medya Yükleme İsteği Verisi kullanıyorsanız Android TV uygulamanıza aşağıdaki önceden tanımlanmış amaç filtresini eklemeniz gerekir:

<activity android:name="com.example.activity">
  <intent-filter>
     <action android:name="com.google.android.gms.cast.tv.action.LOAD"/>
     <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
</activity>

Gönderen tarafında, tüzel kişiye göre yükleme işlemine benzer şekilde, içerik bilgilerinizle bir yükleme isteği oluşturabilir ve load() öğesini çağırabilirsiniz.

Android
Kotlin
val mediaToLoad = MediaInfo.Builder("some-id").build()
val loadRequest = MediaLoadRequestData.Builder()
    .setMediaInfo(mediaToLoad)
    .setCredentials("user-credentials")
    ...
    .build()
remoteMediaClient.load(loadRequest)
Java
MediaInfo mediaToLoad =
    new MediaInfo.Builder("some-id").build();
MediaLoadRequestData loadRequest =
    new MediaLoadRequestData.Builder()
        .setMediaInfo(mediaToLoad)
        .setCredentials("user-credentials")
        ...
        .build();
remoteMediaClient.load(loadRequest);
iOS
let mediaInfoBuilder = GCKMediaInformationBuilder(contentId: "some-id")
...
mediaInformation = mediaInfoBuilder.build()

let mediaLoadRequestDataBuilder = GCKMediaLoadRequestDataBuilder()
mediaLoadRequestDataBuilder.mediaInformation = mediaInformation
mediaLoadRequestDataBuilder.credentials = "user-credentials"
...
let mediaLoadRequestData = mediaLoadRequestDataBuilder.build()

remoteMediaClient?.loadMedia(with: mediaLoadRequestData)
Web

Chromium tarayıcı sürümü M87 veya sonraki bir sürüm gerektirir.

let mediaInfo = new chrome.cast.media.MediaInfo('some-id"', 'video/mp4');
...

let request = new chrome.cast.media.LoadRequest(mediaInfo);
...

cast.framework.CastContext.getInstance().getCurrentSession().loadMedia(request);

Yükleme isteklerini işleme

Etkinliğinizde, bu yükleme isteklerini işlemek için etkinlik yaşam döngüsü geri çağırmalarınızdaki amaçları işlemeniz gerekir:

Kotlin
class MyActivity : Activity() {
  override fun onStart() {
    super.onStart()
    val mediaManager = CastReceiverContext.getInstance().getMediaManager()
    // Pass the intent to the SDK. You can also do this in onCreate().
    if (mediaManager.onNewIntent(intent)) {
        // If the SDK recognizes the intent, you should early return.
        return
    }
    // If the SDK doesn't recognize the intent, you can handle the intent with
    // your own logic.
    ...
  }

  // For some cases, a new load intent triggers onNewIntent() instead of
  // onStart().
  override fun onNewIntent(intent: Intent) {
    val mediaManager = CastReceiverContext.getInstance().getMediaManager()
    // Pass the intent to the SDK. You can also do this in onCreate().
    if (mediaManager.onNewIntent(intent)) {
        // If the SDK recognizes the intent, you should early return.
        return
    }
    // If the SDK doesn't recognize the intent, you can handle the intent with
    // your own logic.
    ...
  }
}
Java
public class MyActivity extends Activity {
  @Override
  protected void onStart() {
    super.onStart();
    MediaManager mediaManager =
        CastReceiverContext.getInstance().getMediaManager();
    // Pass the intent to the SDK. You can also do this in onCreate().
    if (mediaManager.onNewIntent(getIntent())) {
      // If the SDK recognizes the intent, you should early return.
      return;
    }
    // If the SDK doesn't recognize the intent, you can handle the intent with
    // your own logic.
    ...
  }

  // For some cases, a new load intent triggers onNewIntent() instead of
  // onStart().
  @Override
  protected void onNewIntent(Intent intent) {
    MediaManager mediaManager =
        CastReceiverContext.getInstance().getMediaManager();
    // Pass the intent to the SDK. You can also do this in onCreate().
    if (mediaManager.onNewIntent(intent)) {
      // If the SDK recognizes the intent, you should early return.
      return;
    }
    // If the SDK doesn't recognize the intent, you can handle the intent with
    // your own logic.
    ...
  }
}

MediaManager, amacın bir yükleme amacı olduğunu tespit ederse amaçtan bir MediaLoadRequestData nesnesi çıkarır ve MediaLoadCommandCallback.onLoad() yöntemini çağırır. Yükleme isteğini işlemek için bu yöntemi geçersiz kılmanız gerekir. Geri çağırma, MediaManager.onNewIntent() çağrılmadan önce kaydedilmelidir (bir Etkinlik veya Uygulama onCreate() yönteminde olması önerilir).

Kotlin
class MyActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val mediaManager = CastReceiverContext.getInstance().getMediaManager()
        mediaManager.setMediaLoadCommandCallback(MyMediaLoadCommandCallback())
    }
}

class MyMediaLoadCommandCallback : MediaLoadCommandCallback() {
  override fun onLoad(
        senderId: String?,
        loadRequestData: MediaLoadRequestData
  ): Task {
      return Tasks.call {
        // Resolve the entity into your data structure and load media.
        val mediaInfo = loadRequestData.getMediaInfo()
        if (!checkMediaInfoSupported(mediaInfo)) {
            // Throw MediaException to indicate load failure.
            throw MediaException(
                MediaError.Builder()
                    .setDetailedErrorCode(DetailedErrorCode.LOAD_FAILED)
                    .setReason(MediaError.ERROR_REASON_INVALID_REQUEST)
                    .build()
            )
        }
        myFillMediaInfo(MediaInfoWriter(mediaInfo))
        myPlayerLoad(mediaInfo.getContentUrl())

        // Update media metadata and state (this clears all previous status
        // overrides).
        castReceiverContext.getMediaManager()
            .setDataFromLoad(loadRequestData)
        ...
        castReceiverContext.getMediaManager().broadcastMediaStatus()

        // Return the resolved MediaLoadRequestData to indicate load success.
        return loadRequestData
     }
  }

  private fun myPlayerLoad(contentURL: String) {
    myPlayer.load(contentURL)

    // Update the MediaSession state.
    val playbackState: PlaybackStateCompat = Builder()
        .setState(
            player.getState(), player.getPosition(), System.currentTimeMillis()
        )
        ...
        .build()
    mediaSession.setPlaybackState(playbackState)
  }
Java
public class MyActivity extends Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    MediaManager mediaManager =
        CastReceiverContext.getInstance().getMediaManager();
    mediaManager.setMediaLoadCommandCallback(new MyMediaLoadCommandCallback());
  }
}

public class MyMediaLoadCommandCallback extends MediaLoadCommandCallback {
  @Override
  public Task onLoad(String senderId, MediaLoadRequestData loadRequestData) {
    return Tasks.call(() -> {
        // Resolve the entity into your data structure and load media.
        MediaInfo mediaInfo = loadRequestData.getMediaInfo();
        if (!checkMediaInfoSupported(mediaInfo)) {
          // Throw MediaException to indicate load failure.
          throw new MediaException(
              new MediaError.Builder()
                  .setDetailedErrorCode(DetailedErrorCode.LOAD_FAILED)
                  .setReason(MediaError.ERROR_REASON_INVALID_REQUEST)
                  .build());
        }
        myFillMediaInfo(new MediaInfoWriter(mediaInfo));
        myPlayerLoad(mediaInfo.getContentUrl());

        // Update media metadata and state (this clears all previous status
        // overrides).
        castReceiverContext.getMediaManager()
            .setDataFromLoad(loadRequestData);
        ...
        castReceiverContext.getMediaManager().broadcastMediaStatus();

        // Return the resolved MediaLoadRequestData to indicate load success.
        return loadRequestData;
    });
}

private void myPlayerLoad(String contentURL) {
  myPlayer.load(contentURL);

  // Update the MediaSession state.
  PlaybackStateCompat playbackState =
      new PlaybackStateCompat.Builder()
          .setState(
              player.getState(), player.getPosition(), System.currentTimeMillis())
          ...
          .build();
  mediaSession.setPlaybackState(playbackState);
}

Yükleme amacını işlemek için niyeti tanımladığımız veri yapılarına ayrıştırabilirsiniz (yükleme istekleri için MediaLoadRequestData).

Medya komutlarını destekleme

Temel oynatma kontrolü desteği

Temel entegrasyon komutları, medya oturumuyla uyumlu komutları içerir. Bu komutlar medya oturumu geri çağırmaları aracılığıyla bildirilir. Bunu desteklemek için medya oturumuna geri çağırma kaydetmeniz gerekir (bunu zaten yapıyor olabilirsiniz).

Kotlin
private class MyMediaSessionCallback : MediaSessionCompat.Callback() {
  override fun onPause() {
    // Pause the player and update the play state.
    myPlayer.pause()
  }

  override fun onPlay() {
    // Resume the player and update the play state.
    myPlayer.play()
  }

  override fun onSeekTo(pos: Long) {
    // Seek and update the play state.
    myPlayer.seekTo(pos)
  }
    ...
 }

mediaSession.setCallback(MyMediaSessionCallback())
Java
private class MyMediaSessionCallback extends MediaSessionCompat.Callback {
  @Override
  public void onPause() {
    // Pause the player and update the play state.
    myPlayer.pause();
  }
  @Override
  public void onPlay() {
    // Resume the player and update the play state.
    myPlayer.play();
  }
  @Override
  public void onSeekTo(long pos) {
    // Seek and update the play state.
    myPlayer.seekTo(pos);
  }

  ...
}

mediaSession.setCallback(new MyMediaSessionCallback());

Yayınlama kontrol komutlarını destekleme

MediaSession ürününde kullanılamayan bazı skipAd() veya setActiveMediaTracks() komutları vardır. Ayrıca, Yayınlama sırası MediaSession sırası ile tamamen uyumlu olmadığından bazı sıra komutlarının burada uygulanması gerekir.

Kotlin
class MyMediaCommandCallback : MediaCommandCallback() {
    override fun onSkipAd(requestData: RequestData?): Task {
        // Skip your ad
        ...
        return Tasks.forResult(null)
    }
}

val mediaManager = CastReceiverContext.getInstance().getMediaManager()
mediaManager.setMediaCommandCallback(MyMediaCommandCallback())
Java
public class MyMediaCommandCallback extends MediaCommandCallback {
  @Override
  public Task onSkipAd(RequestData requestData) {
    // Skip your ad
    ...
    return Tasks.forResult(null);
  }
}

MediaManager mediaManager =
    CastReceiverContext.getInstance().getMediaManager();
mediaManager.setMediaCommandCallback(new MyMediaCommandCallback());

Desteklenen medya komutlarını belirtin

Yayın alıcınızda olduğu gibi, Android TV uygulamanızda da hangi komutların desteklendiği belirtilmelidir. Böylece, gönderenler belirli kullanıcı arayüzü kontrollerini etkinleştirebilir veya devre dışı bırakabilir. MediaSession kapsamındaki komutlar için komutları PlaybackStateCompat içinde belirtin. Ek komutlar MediaStatusModifier bölümünde belirtilmelidir.

Kotlin
// Set media session supported commands
val playbackState: PlaybackStateCompat = PlaybackStateCompat.Builder()
    .setActions(PlaybackStateCompat.ACTION_PLAY or PlaybackStateCompat.ACTION_PAUSE)
    .setState(PlaybackStateCompat.STATE_PLAYING)
    .build()

mediaSession.setPlaybackState(playbackState)

// Set additional commands in MediaStatusModifier
val mediaManager = CastReceiverContext.getInstance().getMediaManager()
mediaManager.getMediaStatusModifier()
    .setMediaCommandSupported(MediaStatus.COMMAND_QUEUE_NEXT)
Java
// Set media session supported commands
PlaybackStateCompat playbackState =
    new PlaybackStateCompat.Builder()
        .setActions(PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PAUSE)
        .setState(PlaybackStateCompat.STATE_PLAYING)
        .build();

mediaSession.setPlaybackState(playbackState);

// Set additional commands in MediaStatusModifier
MediaManager mediaManager = CastReceiverContext.getInstance().getMediaManager();
mediaManager.getMediaStatusModifier()
            .setMediaCommandSupported(MediaStatus.COMMAND_QUEUE_NEXT);

Desteklenmeyen düğmeleri gizle

Android TV uygulamanız yalnızca temel medya kontrolünü destekliyorsa, ancak Web Alıcı uygulamanız daha gelişmiş kontrolü destekliyorsa, Android TV uygulamasında yayın yaparken gönderen uygulamanızın doğru bir şekilde davrandığından emin olmanız gerekir. Örneğin, Android TV uygulamanız, Web Alıcı uygulamanız desteklerken oynatma hızının değiştirilmesini desteklemiyorsa desteklenen işlemleri her iki platformda da doğru şekilde yapmalı ve gönderen uygulamanızın kullanıcı arayüzünü doğru şekilde oluşturduğundan emin olmalısınız.

Medya Durumunu Değiştirme

Parçalar, reklamlar, canlı yayınlar ve sıraya alma gibi gelişmiş özellikleri desteklemek için Android TV uygulamanızın MediaSession aracılığıyla doğrulanamayan ek bilgiler sağlaması gerekir.

Bu hedefe ulaşmak için MediaStatusModifier sınıfını sağlarız. MediaStatusModifier her zaman CastReceiverContext bölümünde ayarladığınız MediaSession öğesinde çalışır.

Yayınlamak ve yayınlamak için MediaStatus:

Kotlin
val mediaManager: MediaManager = castReceiverContext.getMediaManager()
val statusModifier: MediaStatusModifier = mediaManager.getMediaStatusModifier()

statusModifier
    .setLiveSeekableRange(seekableRange)
    .setAdBreakStatus(adBreakStatus)
    .setCustomData(customData)

mediaManager.broadcastMediaStatus()
Java
MediaManager mediaManager = castReceiverContext.getMediaManager();
MediaStatusModifier statusModifier = mediaManager.getMediaStatusModifier();

statusModifier
    .setLiveSeekableRange(seekableRange)
    .setAdBreakStatus(adBreakStatus)
    .setCustomData(customData);

mediaManager.broadcastMediaStatus();

İstemci kitaplığımız, MediaSession tabanından MediaStatus edinir, Android TV uygulamanız ek MediaStatus durumu belirtebilir ve durumu MediaStatus değiştiricisiyle geçersiz kılabilir.

Bazı durumlar ve meta veriler hem MediaSession hem de MediaStatusModifier içinde ayarlanabilir. Bunları yalnızca MediaSession içinde ayarlamanızı kesinlikle öneririz. MediaSession'daki durumları geçersiz kılmak için değiştiriciyi kullanmaya devam edebilirsiniz. Çünkü değiştiricideki durumun her zaman MediaSession tarafından sağlanan değerlerden daha yüksek bir önceliğe sahip olması önerilir.

Göndermeden önce MediaStatus'a müdahale ediliyor

Web Alıcı SDK'sı ile aynı şekilde, göndermeden önce son rötuşları yapmak isterseniz MediaStatus işlenecek bir MediaStatusInterceptor belirtebilirsiniz. MediaStatus gönderilmeden önce manipüle edilmesi için bir MediaStatusWriter geçiririz.

Kotlin
mediaManager.setMediaStatusInterceptor(object : MediaStatusInterceptor {
    override fun intercept(mediaStatusWriter: MediaStatusWriter) {
      // Perform customization.
        mediaStatusWriter.setCustomData(JSONObject("{data: \"my Hello\"}"))
    }
})
Java
mediaManager.setMediaStatusInterceptor(new MediaStatusInterceptor() {
    @Override
    public void intercept(MediaStatusWriter mediaStatusWriter) {
        // Perform customization.
        mediaStatusWriter.setCustomData(new JSONObject("{data: \"my Hello\"}"));
    }
});

Kullanıcı kimlik bilgilerini işleme

Android TV uygulamanız yalnızca belirli kullanıcıların uygulama oturumunu başlatmasına veya oturuma katılmasına izin verebilir. Örneğin, bir gönderenin yalnızca aşağıdaki durumlarda başlatılmasına veya katılmasına izin verin:

  • Gönderen uygulama, ATV uygulamasıyla aynı hesaba ve profile giriş yaptı.
  • Gönderen uygulama aynı hesaba, ancak ATV uygulamasıyla farklı bir profile giriş yapmış.

Uygulamanız birden fazla veya anonim kullanıcıyı işleyebiliyorsa herhangi bir kullanıcının ATV oturumuna katılmasına izin verebilirsiniz. Kullanıcı kimlik bilgilerini sağlıyorsa ilerleme durumunun ve diğer kullanıcı verilerinin düzgün şekilde izlenebilmesi için ATV uygulamanızın kimlik bilgilerini işlemesi gerekir.

Gönderen uygulamanız Android TV uygulamanızı başlattığında veya bu uygulamaya katıldığında, gönderen uygulamanız oturuma kimlerin katıldığını gösteren kimlik bilgilerini sağlamalıdır.

Bir gönderen, Android TV uygulamanızı başlatıp katılmadan önce, gönderen kimlik bilgilerine izin verilip verilmediğini görmek için bir başlatma denetleyicisi belirtebilirsiniz. Aksi takdirde, Cast Connect SDK'sı Web Alıcınızı başlatır.

Gönderen uygulamayı başlatma kimlik bilgisi verileri

Gönderen tarafta, oturuma katılanları CredentialsData olarak belirtebilirsiniz.

credentials, ATV uygulamanız tarafından anlaşılabildiği sürece kullanıcı tarafından tanımlanabilen bir dizedir. credentialsType, CredentialsData öğesinin hangi platformdan geldiğini tanımlar veya özel bir değer olabilir. Varsayılan olarak, gönderildiği platforma ayarlanır.

CredentialsData yalnızca Android TV uygulamanıza lansman veya katılma sırasında iletilir. Bağlanırken bağlantı oluşturursanız bu ayar Android TV uygulamanıza iletilmez. Göndereniniz bağlıyken profili değiştirirse oturumda kalabilir veya yeni profilin oturumla uyumlu olmadığını düşünüyorsanız SessionManager.endCurrentCastSession(boolean stopCasting) numaralı telefonu arayabilirsiniz.

Her bir gönderenin CredentialsData mesajı, CastReceiverContext üzerinde SenderInfo aracını almak için getSenders ve getCastLaunchRequest() almak için CastLaunchRequest ve ardından getCredentialsData() alınabilir.

Android

play-services-cast-framework 19.0.0 veya daha yeni bir sürüm gerekir.

Kotlin
CastContext.getSharedInstance().setLaunchCredentialsData(
    CredentialsData.Builder()
        .setCredentials("{\"userId\": \"abc\"}")
        .build()
)
Java
CastContext.getSharedInstance().setLaunchCredentialsData(
    new CredentialsData.Builder()
        .setCredentials("{\"userId\": \"abc\"}")
        .build());
iOS

google-cast-sdk v4.7.0 veya daha yeni bir sürüm gerekir.

Seçenekler ayarlandıktan sonra istenildiği zaman çağrılabilir: GCKCastContext.setSharedInstanceWith(options).

GCKCastContext.sharedInstance().setLaunch(
    GCKCredentialsData(credentials: "{\"userId\": \"abc\"}")
Web

Chromium tarayıcı sürümü M87 veya sonraki bir sürüm gerektirir.

Seçenekler ayarlandıktan sonra istenildiği zaman çağrılabilir: cast.framework.CastContext.getInstance().setOptions(options);.

let credentialsData =
    new chrome.cast.CredentialsData("{\"userId\": \"abc\"}");
cast.framework.CastContext.getInstance().setLaunchCredentialsData(credentialsData);

ATV başlatma isteği denetleyicisini uygulama

Bir gönderen başlatılmaya veya katılmaya çalıştığında CredentialsData Android TV uygulamanıza iletilir. LaunchRequestChecker etiketini uygulayabilirsiniz. onaylayın veya reddedin.

İstek reddedilirse yerel olarak ATV uygulamasında başlatılması yerine Web Alıcısı yüklenir. ATV'niz başlatma veya katılma isteğinde bulunan kullanıcıyı yönetemiyorsa bir isteği reddetmeniz gerekir. ATV uygulamasına istekte bulunandan farklı bir kullanıcının giriş yapması ve uygulamanızın kimlik bilgilerini değiştirme işlemini gerçekleştirememesi veya şu anda ATV uygulamasında oturum açmış bir kullanıcı olmaması buna örnek gösterilebilir.

İsteğe izin verilirse ATV uygulaması başlatılır. Bu davranışı, kullanıcı ATV uygulamasında oturum açmadığında veya kullanıcı uyuşmazlığı durumunda uygulamanızın yükleme isteği gönderme özelliğini destekleyip desteklemediğine göre özelleştirebilirsiniz. Bu davranış, LaunchRequestChecker içinde tamamen yerelleştirilebilir.

CastReceiverOptions.LaunchRequestChecker arayüzünü kullanarak bir sınıf oluşturun:

Kotlin
class MyLaunchRequestChecker : LaunchRequestChecker {
  override fun checkLaunchRequestSupported(launchRequest: CastLaunchRequest): Task {
    return Tasks.call {
      myCheckLaunchRequest(
           launchRequest
      )
    }
  }
}

private fun myCheckLaunchRequest(launchRequest: CastLaunchRequest): Boolean {
  val credentialsData = launchRequest.getCredentialsData()
     ?: return false // or true if you allow anonymous users to join.

  // The request comes from a mobile device, e.g. checking user match.
  return if (credentialsData.credentialsType == CredentialsData.CREDENTIALS_TYPE_ANDROID) {
     myCheckMobileCredentialsAllowed(credentialsData.getCredentials())
  } else false // Unrecognized credentials type.
}
Java
public class MyLaunchRequestChecker
    implements CastReceiverOptions.LaunchRequestChecker {
  @Override
  public Task checkLaunchRequestSupported(CastLaunchRequest launchRequest) {
    return Tasks.call(() -> myCheckLaunchRequest(launchRequest));
  }
}

private boolean myCheckLaunchRequest(CastLaunchRequest launchRequest) {
  CredentialsData credentialsData = launchRequest.getCredentialsData();
  if (credentialsData == null) {
    return false;  // or true if you allow anonymous users to join.
  }

  // The request comes from a mobile device, e.g. checking user match.
  if (credentialsData.getCredentialsType().equals(CredentialsData.CREDENTIALS_TYPE_ANDROID)) {
    return myCheckMobileCredentialsAllowed(credentialsData.getCredentials());
  }

  // Unrecognized credentials type.
  return false;
}

Ardından, bu ayarı ReceiverOptionsProvider bölümüne ayarlayın:

Kotlin
class MyReceiverOptionsProvider : ReceiverOptionsProvider {
  override fun getOptions(context: Context?): CastReceiverOptions {
    return CastReceiverOptions.Builder(context)
        ...
        .setLaunchRequestChecker(MyLaunchRequestChecker())
        .build()
  }
}
Java
public class MyReceiverOptionsProvider implements ReceiverOptionsProvider {
  @Override
  public CastReceiverOptions getOptions(Context context) {
    return new CastReceiverOptions.Builder(context)
        ...
        .setLaunchRequestChecker(new MyLaunchRequestChecker())
        .build();
  }
}

LaunchRequestChecker'te true çözümlendiğinde ATV uygulaması, false ise Web Alıcı uygulamanızı başlatır.

Özel Mesaj Gönderme ve Alma

Yayın protokolü, gönderenler ve alıcı uygulamanız arasında özel dize mesajları göndermenize olanak tanır. CastReceiverContext işleminizi başlatmadan önce mesaj göndermek için bir ad alanı (kanal) kaydetmeniz gerekir.

Android TV - Özel Ad Alanı Belirtin

Kurulum sırasında CastReceiverOptions bölümünüzde desteklenen ad alanlarınızı belirtmeniz gerekir:

Kotlin
class MyReceiverOptionsProvider : ReceiverOptionsProvider {
  override fun getOptions(context: Context?): CastReceiverOptions {
    return CastReceiverOptions.Builder(context)
        .setCustomNamespaces(
            Arrays.asList("urn:x-cast:com.example.cast.mynamespace")
        )
        .build()
  }
}
Java
public class MyReceiverOptionsProvider implements ReceiverOptionsProvider {
  @Override
  public CastReceiverOptions getOptions(Context context) {
    return new CastReceiverOptions.Builder(context)
        .setCustomNamespaces(
              Arrays.asList("urn:x-cast:com.example.cast.mynamespace"))
        .build();
  }
}

Android TV: Mesaj Gönderme

Kotlin
// If senderId is null, then the message is broadcasted to all senders.
CastReceiverContext.getInstance().sendMessage(
    "urn:x-cast:com.example.cast.mynamespace", senderId, customString)
Java
// If senderId is null, then the message is broadcasted to all senders.
CastReceiverContext.getInstance().sendMessage(
    "urn:x-cast:com.example.cast.mynamespace", senderId, customString);

Android TV - Özel Ad Alanı Mesajları Alın

Kotlin
class MyCustomMessageListener : MessageReceivedListener {
    override fun onMessageReceived(
        namespace: String, senderId: String?, message: String ) {
        ...
    }
}

CastReceiverContext.getInstance().setMessageReceivedListener(
    "urn:x-cast:com.example.cast.mynamespace", new MyCustomMessageListener());
Java
class MyCustomMessageListener implements CastReceiverContext.MessageReceivedListener {
  @Override
  public void onMessageReceived(
      String namespace, String senderId, String message) {
    ...
  }
}

CastReceiverContext.getInstance().setMessageReceivedListener(
    "urn:x-cast:com.example.cast.mynamespace", new MyCustomMessageListener());