Android TV alıcınıza temel özellikler ekleme

Bu sayfada, bir Android TV Alıcı uygulamasını özelleştirmek için kullanılabilen kod snippet'leri ve özelliklerin açıklamaları yer alır.

Kitaplıkları yapılandırma

Cast Connect API'lerinin Android TV uygulamanızda kullanılabilmesi için:

Android
  1. Uygulama modülü dizininizde build.gradle dosyasını açın.
  2. google() öğesinin listelenen repositories içinde bulunduğunu doğrulayın.
      repositories {
        google()
      }
  3. Uygulamanız için hedef cihaz türünüze bağlı olarak kitaplıkların en yeni sürümlerini bağımlılıklarınıza ekleyin:
    • Android Alıcı uygulaması için:
        dependencies {
          implementation 'com.google.android.gms:play-services-cast-tv:21.1.0'
          implementation 'com.google.android.gms:play-services-cast:21.5.0'
        }
    • Android Sender uygulaması için:
        dependencies {
          implementation 'com.google.android.gms:play-services-cast:21.1.0'
          implementation 'com.google.android.gms:play-services-cast-framework:21.5.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ğundaki Sync Project with Gradle Files simgesini tıklayın.
iOS
  1. Podfile uygulamanızın google-cast-sdk 4.8.1 veya sonraki bir sürümü hedeflediğinden emin olun
  2. iOS 14 veya sonraki sürümleri hedefleyin. Daha fazla bilgi için Sürüm Notları'na göz atın.
      platform: ios, '14'
    
      def target_pods
         pod 'google-cast-sdk', '~>4.8.1'
      end
Web
  1. Chromium tarayıcı M87 veya sonraki sürümünü gerektirir.
  2. Web Sender 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ümleri, bir uygulamanın androidx ad alanını kullanacak şekilde güncellenmesini gerektirir. AndroidX'e taşıma talimatlarını uygulayın.

Android TV uygulaması ile ilgili ön koşullar

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

Medya oturumu ve medya oturumunun nasıl başlatılacağı hakkında daha fazla bilgi için medya oturumuyla çalışma rehberine 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 serbest bırakmalıdır. Örneğin, uygulamanız bir video uygulamasıysa kullanıcı oynatma etkinliğinden çıktığında oturumu serbest bırakmalısınız. Bunun için diğer içeriklere göz atmak için "geri"yi seçebilir veya uygulamayı arka plana alabilirsiniz. Uygulamanız bir müzik uygulamasıysa uygulamanız artık hiçbir medya oynatmadığında serbest bırakmalısınız.

Oturum durumu güncelleniyor

Medya oturumunuzdaki veriler, oynatıcınızın durumuyla ilgili güncel tutulmalıdır. Örneğin, oynatma duraklatıldığında desteklenen işlemlerin yanı sıra oynatma durumunu da güncellemeniz gerekir. Aşağıdaki tablolarda, güncel tutmaktan sorumlu olduğunuz eyaletler listelenmiştir.

MediaMetadataCompat

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

PlaybackStateCompat

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

MediaSessionCompat

Gerekli Yöntem Açıklama
setRepeatMode() Tekrarlama modunu ayarlar.
setShuffleMode() Karıştırma modunu ayarlar.
setMetadata() Medya meta verilerini ayarlar.
setPlaybackState() 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);
}

Aktarım kontrolünü işleme

Uygulamanızda medya oturumu aktarım kontrolü geri çağırması uygulanmalıdır. Aşağıdaki tabloda, yürütmeleri gereken aktarım kontrolü işlemleri gösterilmektedir:

MediaSessionCompat.Callback

İşlemler Açıklama
onPlay() Devam ettir
onPause() Duraklat
onSeekTo() Bir konuma sar
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());

Cast desteğini yapılandırma

Bir gönderen uygulaması tarafından başlatma isteği gönderildiğinde, uygulama ad alanıyla bir amaç oluşturulur. Uygulamanız bunu işlemekten ve TV uygulaması başlatıldığında CastReceiverContext nesnesinin bir örneğini oluşturmaktan sorumludur. TV uygulaması çalışırken Cast 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ını belirtin

CastReceiverOptions 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 sayfanızda seçenek sağlayıcıyı 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 sağlamak için kullanılır.

Yayın alıcı bağlamı

Uygulamanız oluşturulduğunda CastReceiverContext'i 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 modunu başlatın:

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

Arka planda oynatmayı desteklemeyen video uygulamaları veya uygulamalar için arka plana geçtikten sonra stop() CastReceiverContext 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 cihazında stop() yöntemini ç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 sayede, farklı etkinliklerden start() ve stop() çağırırken yarış koşulları yaşamazsınız.

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

MediaSession oluşturduğunuzda, komutların nereye gönderileceğini ve medya oynatma durumunu alması için CastReceiverContext'e geçerli MediaSession jetonunu da 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 öğenizi serbest bıraktığınızda MediaManager üzerinde boş 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önderilirken CastReceiverContext.stop() numarasını aramak yerine çağrıyı yalnızca uygulamanız arka planda çalışırken ve artık medya oynatmadığında çağırmalısınız. Ö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();
  }
}

Exoplayer'ı Cast Connect ile kullanma

Exoplayer kullanıyorsanız değişiklikleri manuel olarak izlemek yerine, oturumu ve oynatma durumu dahil tüm ilgili bilgileri otomatik olarak sürdürmek için MediaSessionConnector aracını kullanabilirsiniz.

MediaSessionConnector.MediaButtonEventHandler, varsayılan olarak MediaSessionCompat.Callback tarafından işlenen setMediaButtonEventHandler(MediaButtonEventHandler) çağrısıyla MediaButton etkinliklerini işlemek için kullanılabilir.

MediaSessionConnector'i uygulamanıza entegre etmek için oynatıcı etkinliği sınıfınıza veya medya oturumunuzu yönettiğiniz herhangi bir yere aşağıdakileri 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ının kurulumu

Cast Connect desteğini etkinleştir

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 beyan edebilirsiniz.

Android

play-services-cast-framework 19.0.0 veya sonraki bir sürümü gerektirir.

androidReceiverCompatible işareti, CastOptions öğesinin bir parçası olan LaunchOptions konumunda ayarlanı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 sonraki bir sürümü gerektirir.

androidReceiverCompatible işareti, GCKCastOptions öğesinin bir parçası olan GCKLaunchOptions konumunda ayarlanı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 sürümleri 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 Uygulaması Kimliğinizle ilişkilendirmek için Cast Developer Console'a ekleyin.

Geliştirici cihazlarını kaydedin

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 kayıt olmadan yalnızca Google Play Store'dan yüklenen uygulamalarda çalışır.

Bir Cast veya Android TV cihazını Cast geliştirme için kaydettirme hakkında daha fazla bilgi edinmek üzere kayıt sayfasına bakın.

Medya yükleniyor

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

<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önderendeki varlığa göre yükle

Gönderenlerde, yükleme isteği için 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 sürümleri 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ıyla bir intent aracılığıyla gönderilir.

Gönderende 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ı bu iki platformda farklı şekilde yapıyorsanız). Bu sorunu gidermek amacıyla 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 sürümleri 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 Buyer uygulaması başlatılırsa yükleme isteğinde entity ve credentials kullanılır. Ancak Android TV uygulamanız başlatılırsa SDK, entity ve credentials değerlerini atvEntity ve atvCredentials (belirtilmişse) ile geçersiz kılar.

Content ID veya MediaQueueData ile yükleme

entity veya atvEntity kullanmıyorsanız ve Medya Bilgilerinizde Content ID veya Content URL'si kullanıyorsanız ya da daha ayrıntılı Medya Yükleme İsteği Verilerini kullanıyorsanız Android TV uygulamanıza aşağıdaki önceden tanımlanmış intent 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, varlığa göre yüklemeye benzer şekilde, içerik bilgilerinizle bir yükleme isteği oluşturabilir ve load() yöntemini ç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 sürümleri 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ı ele almanız 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 yükleme amacı olduğunu algılarsa amaçtan bir MediaLoadRequestData nesnesi çıkarıp MediaLoadCommandCallback.onLoad() ç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 (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 amacı, tanımladığımız veri yapılarına (yükleme istekleri için MediaLoadRequestData) ayrıştırabilirsiniz.

Medya komutlarını destekleme

Temel oynatma kontrolü desteği

Temel entegrasyon komutları, medya oturumuyla uyumlu olan komutları içerir. Bu komutlar medya oturumu geri çağırmaları aracılığıyla bildirilir. Bunu desteklemek için bir 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ın kontrolü komutlarını destekleme

MediaSession içinde kullanılamayan bazı Cast komutları (ör. skipAd() veya setActiveMediaTracks()) vardır. Ayrıca, Yayınlama sırası MediaSession sırası ile tam olarak uyumlu olmadığından bazı sıra komutlarının burada uygulanması gerekiyor.

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ı belirtme

Yayın alıcınızda olduğu gibi, Android TV uygulamanızın hangi komutların desteklendiğini belirtmesi gerekir. Böylece gönderenler, belirli kullanıcı arayüzü kontrollerini etkinleştirebilir veya devre dışı bırakabilir. MediaSession kapsamındaki komutlar için PlaybackStateCompat bölümünde komutları 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ü desteklemesine rağmen Web Alıcı uygulamanız daha gelişmiş kontrolleri destekliyorsa, gönderen uygulamanızın Android TV uygulamasına yayın yaparken doğru davrandığından emin olmalısınız. Örneğin, Android TV uygulamanız, Web Alıcı uygulamanız gösterirken oynatma hızını değiştirmeyi desteklemiyorsa, desteklenen işlemleri her platformda doğru şekilde ayarlamanız ve gönderen uygulamanızın, kullanıcı arayüzünü doğru şekilde oluşturduğundan emin olmanız gerekir.

MediaStatus değiştiriliyor

Parça, reklam, canlı yayın ve sıraya alma gibi gelişmiş özellikleri desteklemek için Android TV uygulamanızın, MediaSession aracılığıyla tespit edilemeyen ek bilgiler sağlaması gerekir.

Bunu başarmanız için MediaStatusModifier sınıfını sunuyoruz. MediaStatusModifier her zaman CastReceiverContext üzerinde ayarladığınız MediaSession üzerinde çalışır.

MediaStatus oluşturmak ve yayınlamak için:

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 uygulamasından temel MediaStatus öğesini alır. Android TV uygulamanız, MediaStatus değiştiriciyle ek durum ve geçersiz kılma durumu belirtebilir.

Bazı durumlar ve meta veriler hem MediaSession hem de MediaStatusModifier içinde ayarlanabilir. Bunları yalnızca MediaSession içinde ayarlamanızı kesinlikle öneririz. MediaSession içindeki durumları geçersiz kılmak için yine de değiştiriciyi kullanabilirsiniz. Değiştiricideki durum, MediaSession tarafından sağlanan değerlerden her zaman daha yüksek önceliğe sahip olduğu için bu önerilmez.

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

Web Receiver SDK'da olduğu gibi, göndermeden önce son rötuşları yapmak istiyorsanız gönderilecek MediaStatus öğesinin işlenmesi için bir MediaStatusInterceptor belirtebilirsiniz. MediaStatus öğesini gönderilmeden önce değiştirmek için bir MediaStatusWriter iletiriz.

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 veriyor olabilir. Örneğin, 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ş yapar.
  • Gönderen uygulama, ATV uygulamasıyla aynı hesaba ancak farklı profile giriş yapmış.

Uygulamanız birden fazla veya anonim kullanıcıyı işleyebiliyorsa başka herhangi bir kullanıcının ATV oturumuna katılmasına izin verebilirsiniz. Kullanıcı kimlik bilgilerini sağlarsa ATV uygulamanızın, ilerleme durumunun ve diğer kullanıcı verilerinin doğru şekilde izlenebilmesi için bu kullanıcıların kimlik bilgilerini işlemesi gerekir.

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

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şlatmaya başlar.

Gönderen uygulama başlatma kimlik bilgileri ile ilgili veriler

Gönderen tarafında, oturuma kimlerin katılacağını CredentialsData olarak belirtebilirsiniz.

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

CredentialsData, Android TV uygulamanıza yalnızca lansman veya katılma sırasında aktarılır. İnternete bağlıyken tekrar ayarlarsanız Android TV uygulamanıza aktarılmaz. Gönderen kişi profil açıkken 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 gönderen için CredentialsData, CastReceiverContext üzerinden getSenders kullanılarak alınabilir. SenderInfo'ı almak için getCastLaunchRequest(), CastLaunchRequest ve ardından getCredentialsData() kullanılabilir.

Android

play-services-cast-framework 19.0.0 veya sonraki bir sürümü gerektirir.

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.8.1 veya sonraki bir sürümü gerektirir.

Seçenekler belirlendikten sonra herhangi bir zamanda çağrılabilir: GCKCastContext.setSharedInstanceWith(options).

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

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

Seçenekler belirlendikten sonra herhangi bir zamanda çağrılabilir: cast.framework.CastContext.getInstance().setOptions(options);.

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

ATV lansman isteği denetleyiciyi uygulama

Bir gönderen uygulamayı başlatmaya veya katılmaya çalıştığında CredentialsData, Android TV uygulamanıza iletilir. LaunchRequestChecker uygulayabilirsiniz. seçeneğini tıklayın.

Bir istek reddedilirse ATV uygulamasında yerel olarak başlatmak yerine Web Alıcı yüklenir. ATV'niz, başlatma veya katılma isteğini yerine getiremiyorsa isteği reddetmeniz gerekir. Örnek olarak, ATV uygulamasına istekte bulunandan farklı bir kullanıcının giriş yapmış olması ve uygulamanızın, geçiş kimlik bilgilerini işleyememesi veya şu anda ATV uygulamasına giriş yapan bir kullanıcının bulunmaması olabilir.

Bir isteğe izin verilirse ATV uygulaması başlatılır. Bir kullanıcı ATV uygulamasına giriş yapmadığında uygulamanızın yükleme isteği göndermeyi destekleyip desteklemediğine veya kullanıcı uyuşmazlığına göre bu davranışı özelleştirebilirsiniz. Bu davranış LaunchRequestChecker içinde tamamen özelleştirilebilir.

CastReceiverOptions.LaunchRequestChecker arayüzünü uygulayan 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 ReceiverOptionsProvider içinde 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 içindeki true çözümlendiğinde ATV uygulaması başlatılır, false ise Web Alıcı uygulamanızı başlatır.

Özel Mesaj Gönderme ve Alma

Cast protokolü, gönderenler ile alıcı uygulamanız arasında özel dize mesajları göndermenizi sağlar. CastReceiverContext'inizi 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'te 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 - Mesajlar Gönderiliyor

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ı Alma

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());