Wichtige Funktionen zu Ihrem Android TV-Receiver hinzufügen

Diese Seite enthält Code-Snippets und Beschreibungen der Funktionen, die für Anpassen einer Android TV Receiver App

Bibliotheken konfigurieren

So machen Sie Cast Connect APIs für Ihre Android TV App verfügbar:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Android
  1. Öffnen Sie die Datei build.gradle im Verzeichnis Ihres Anwendungsmoduls.
  2. Prüfe, ob google() im aufgeführten repositories enthalten ist.
      repositories {
        google()
      }
  3. Fügen Sie je nach Zielgerätetyp Ihrer App die neuesten Versionen hinzu der Bibliotheken zu Ihren Abhängigkeiten hinzu: <ph type="x-smartling-placeholder">
      </ph>
    • Android Receiver-App:
        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-App:
        dependencies {
          implementation 'com.google.android.gms:play-services-cast:21.1.0'
          implementation 'com.google.android.gms:play-services-cast-framework:21.5.0'
        }
    Achten Sie darauf, diese Versionsnummer bei jeder Aktualisierung der Dienste zu aktualisieren.
  4. Speichern Sie die Änderungen und klicken Sie auf Sync Project with Gradle Files. in der Symbolleiste.
<ph type="x-smartling-placeholder">
</ph>
iOS
  1. Podfile muss auf google-cast-sdk ausgerichtet sein 4.8.3 oder höher
  2. Richten Sie Ihre App auf iOS 14 oder höher aus. Siehe Versionshinweise .
      platform: ios, '14'
    
      def target_pods
         pod 'google-cast-sdk', '~>4.8.3'
      end
<ph type="x-smartling-placeholder">
</ph>
Web
  1. Erfordert die Chromium-Browserversion M87 oder höher.
  2. Web Sender API-Bibliothek zum Projekt hinzufügen
      <script src="//www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>

AndroidX-Anforderung

Für neue Versionen der Google Play-Dienste muss eine App aktualisiert werden, damit sie verwendet werden können den Namespace androidx. Folgen Sie der Anleitung für die Migration zu AndroidX durchzuführen.

Android TV App – Voraussetzungen

Damit Cast Connect in deiner Android TV App unterstützt wird, musst du Support-Ereignisse aus einer Mediensitzung. Die von Ihrer Mediensitzung bereitgestellten Daten enthält die grundlegenden Informationen – zum Beispiel Position, Wiedergabestatus usw. – für Ihren Medienstatus. Deine Mediensitzung wird auch von der Cast Connect-Bibliothek verwendet um zu signalisieren, dass bestimmte Nachrichten von einem Absender eingegangen sind, z. B. „Pause“.

Weitere Informationen zu Mediensitzungen und zum Initialisieren einer Mediensitzung finden Sie unter sieh dir die mit einem Leitfaden für Mediensitzungen.

Lebenszyklus von Mediensitzungen

Ihre App sollte zu Beginn der Wiedergabe eine Mediensitzung erstellen und sie loslassen, wenn kann er nicht mehr gesteuert werden. Wenn es sich z. B. um eine Video-App handelt, sollte die Sitzung freigeben, wenn der Nutzer die Wiedergabeaktivität beendet – entweder durch Auswahl von „Zurück“ um andere Inhalte zu durchsuchen oder die App im Hintergrund zu starten. Wenn Ihr App eine Musik-App ist, solltest du sie veröffentlichen, wenn in deiner App keine Wiedergabe mehr läuft Medien.

Sitzungsstatus wird aktualisiert

Die Daten in Ihrer Mediensitzung sollten stets auf dem neuesten Stand sein, Player. Wenn die Wiedergabe beispielsweise pausiert ist, solltest du die Wiedergabe- Status sowie die unterstützten Aktionen. In den folgenden Tabellen sind die Status aufgeführt. sind Sie dafür verantwortlich, auf dem Laufenden zu bleiben.

MediaMetadataCompat

Metadatenfeld Beschreibung
METADATA_KEY_TITLE (erforderlich) Der Medientitel.
METADATA_KEY_DISPLAY_SUBTITLE Die Unterüberschrift.
METADATA_KEY_DISPLAY_ICON_URI Die Symbol-URL.
METADATA_KEY_DURATION (erforderlich) Mediendauer.
METADATA_KEY_MEDIA_URI Content ID
METADATA_KEY_ARTIST Der Künstler.
METADATA_KEY_ALBUM Das Album.

PlaybackStateCompat

Erforderliche Methode Beschreibung
setActions() Legt unterstützte Medienbefehle fest.
setState() Wiedergabestatus und aktuelle Position festlegen

MediaSessionCompat

Erforderliche Methode Beschreibung
setRepeatMode() Legt den Wiederholungsmodus fest.
setShuffleMode() Legt den Zufallsmix fest.
setMetadata() Legt Medienmetadaten fest.
setPlaybackState() Legt den Wiedergabestatus fest.
<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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)
}
<ph type="x-smartling-placeholder">
</ph>
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);
}

Transportsteuerung handhaben

In Ihrer App sollte ein Callback für die Steuerung der Mediensitzungstransport implementiert sein. Die Die folgende Tabelle zeigt, welche Transportsteuerungsaktionen verarbeitet werden müssen:

MediaSessionCompat.Callback

Aktionen Beschreibung
onPlay() Fortsetzen
onPause() Pausieren
onSeekTo() Zu einer Position springen
onStop(). Aktuelle Medien anhalten
<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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() );
<ph type="x-smartling-placeholder">
</ph>
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-Unterstützung konfigurieren

Wenn eine Senderanwendung eine Startanfrage sendet, wird ein Intent erstellt durch einen Anwendungs-Namespace. Ihre Anwendung ist für deren Verarbeitung verantwortlich und eine Instanz des CastReceiverContext -Objekt zurückgegeben, wenn die TV-App gestartet wird. Das Objekt CastReceiverContext ist erforderlich um mit Cast zu interagieren, während die TV-App ausgeführt wird. Dieses Objekt ermöglicht deinem Fernseher um gestreamte Medien-Nachrichten von beliebigen verbundenen Absendern zu akzeptieren.

Einrichtung von Android TV

Startabsichtsfilter hinzufügen

Fügen Sie der Aktivität, für die Sie den Start verarbeiten möchten, einen neuen Intent-Filter hinzu Intent aus der Absender-App an:

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

Anbieter von Empfängeroptionen angeben

Sie müssen eine ReceiverOptionsProvider um CastReceiverOptions:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Kotlin
class MyReceiverOptionsProvider : ReceiverOptionsProvider {
  override fun getOptions(context: Context?): CastReceiverOptions {
    return CastReceiverOptions.Builder(context)
          .setStatusText("My App")
          .build()
    }
}
<ph type="x-smartling-placeholder">
</ph>
Java
public class MyReceiverOptionsProvider implements ReceiverOptionsProvider {
  @Override
  public CastReceiverOptions getOptions(Context context) {
    return new CastReceiverOptions.Builder(context)
        .setStatusText("My App")
        .build();
  }
}

Geben Sie dann den Optionsanbieter in AndroidManifest an:

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

ReceiverOptionsProvider wird verwendet, um die CastReceiverOptions bereitzustellen, wenn CastReceiverContext wurde initialisiert.

Kontext des Streamingempfängers

Initialisieren Sie das CastReceiverContext wenn Ihre Anwendung erstellt wird:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Kotlin
override fun onCreate() {
  CastReceiverContext.initInstance(this)

  ...
}
<ph type="x-smartling-placeholder">
</ph>
Java
@Override
public void onCreate() {
  CastReceiverContext.initInstance(this);

  ...
}

Starten Sie CastReceiverContext, wenn Ihre App in den Vordergrund verschoben wird:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Kotlin
CastReceiverContext.getInstance().start()
<ph type="x-smartling-placeholder">
</ph>
Java
CastReceiverContext.getInstance().start();

Anruf stop() am CastReceiverContext nachdem die App bei Video-Apps in den Hintergrund verschoben wurde oder Apps, die keine Hintergrundwiedergabe:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Kotlin
// Player has stopped.
CastReceiverContext.getInstance().stop()
<ph type="x-smartling-placeholder">
</ph>
Java
// Player has stopped.
CastReceiverContext.getInstance().stop();

Wenn deine App die Wiedergabe im Hintergrund unterstützt, rufe außerdem stop() auf. auf dem CastReceiverContext, wenn die Wiedergabe im Hintergrund beendet wird.

Wir empfehlen dringend, den LifecycleObserver aus der androidx.lifecycle Bibliothek zum Verwalten von Anrufen CastReceiverContext.start() und CastReceiverContext.stop() vor allem, wenn Ihre native App mehrere Aktivitäten hat. Dadurch wird Rennen vermieden wenn Sie start() und stop() aus verschiedenen Aktivitäten aufrufen.

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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())
  }
}
<ph type="x-smartling-placeholder">
</ph>
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 mit MediaManager verbinden

Wenn Sie eine MediaSession, Sie müssen auch das aktuelle MediaSession-Token für CastReceiverContext um die Befehle zu senden und den Status der Medienwiedergabe abzurufen:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Kotlin
val mediaManager: MediaManager = receiverContext.getMediaManager()
mediaManager.setSessionCompatToken(currentMediaSession.getSessionToken())
<ph type="x-smartling-placeholder">
</ph>
Java
MediaManager mediaManager = receiverContext.getMediaManager();
mediaManager.setSessionCompatToken(currentMediaSession.getSessionToken());

Wenn du MediaSession wegen inaktiver Wiedergabe loslässt, solltest du eine Null-Token aktiviert MediaManager:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Kotlin
myPlayer.stop()
mediaSession.release()
mediaManager.setSessionCompatToken(null)
<ph type="x-smartling-placeholder">
</ph>
Java
myPlayer.stop();
mediaSession.release();
mediaManager.setSessionCompatToken(null);

Wenn deine App die Wiedergabe von Medien unterstützt, während die App im Hintergrund ausgeführt wird, des Anrufs CastReceiverContext.stop() wenn Ihre App in den Hintergrund verschoben wird, sollten Sie sie nur dann aufrufen, wenn Ihre App im Hintergrund ausgeführt wird und keine Medien mehr abgespielt werden. Beispiel:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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()
  }
}
<ph type="x-smartling-placeholder">
</ph>
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 mit Cast Connect verwenden

Wenn Sie Exoplayer können Sie den MediaSessionConnector um die Sitzung und alle zugehörigen Informationen automatisch aufrechtzuerhalten, einschließlich der Wiedergabestatus statt, anstatt die Änderungen manuell nachzuverfolgen.

MediaSessionConnector.MediaButtonEventHandler kann zur Verarbeitung von MediaButton-Ereignissen verwendet werden, indem setMediaButtonEventHandler(MediaButtonEventHandler) die sonst von der MediaSessionCompat.Callback ist standardmäßig aktiviert.

So integrieren Sie MediaSessionConnector in Ihrer App, fügen Sie Folgendes Ihrer Spieleraktivitätsklasse hinzu oder Mediensitzung verwalten:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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)
    ...
  }
}
<ph type="x-smartling-placeholder">
</ph>
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);
    ...
  }
}

Einrichtung der Sender-App

Cast Connect-Unterstützung aktivieren

Sobald Sie Ihre Absender-App mit der Cast Connect-Unterstützung aktualisiert haben, können Sie ihre Bereitschaft, indem Sie das Attribut androidReceiverCompatible Flagge aktivieren LaunchOptions auf true gesetzt.

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Android

Version play-services-cast-framework erforderlich 19.0.0 oder höher.

Das Flag androidReceiverCompatible wird festgelegt in LaunchOptions (gehört zu CastOptions):

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Kotlin
class CastOptionsProvider : OptionsProvider {
  override fun getCastOptions(context: Context?): CastOptions {
    val launchOptions: LaunchOptions = Builder()
          .setAndroidReceiverCompatible(true)
          .build()
    return CastOptions.Builder()
          .setLaunchOptions(launchOptions)
          ...
          .build()
    }
}
<ph type="x-smartling-placeholder">
</ph>
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();
  }
}
<ph type="x-smartling-placeholder">
</ph>
iOS

Erfordert google-cast-sdk Version v4.4.8 oder höher liegen.

Das Flag androidReceiverCompatible wird festgelegt in GCKLaunchOptions (gehört zu GCKCastOptions):

let options = GCKCastOptions(discoveryCriteria: GCKDiscoveryCriteria(applicationID: kReceiverAppID))
...
let launchOptions = GCKLaunchOptions()
launchOptions.androidReceiverCompatible = true
options.launchOptions = launchOptions
GCKCastContext.setSharedInstanceWith(options)
<ph type="x-smartling-placeholder">
</ph>
Web

Chromium-Browserversion erforderlich M87 oder höher.

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

Einrichtung der Cast Developer Console

Android TV App konfigurieren

Fügen Sie den Paketnamen Ihrer Android TV-App hinzu in Cast-Entwicklerkonsole um ihn mit Ihrer Cast App-ID zu verknüpfen.

Entwicklergeräte registrieren

Registrieren Sie die Seriennummer des Android TV-Geräts, das Sie verwenden möchten für die Entwicklung in der Cast-Entwicklerkonsole

Ohne Registrierung funktioniert Cast Connect nur mit Apps, die über die Google Play Store.

Weitere Informationen zur Registrierung eines Cast- oder Android TV-Geräts für Cast finden Sie auf der Registrierungsseite.

Medien werden geladen

Wenn Sie bereits Deeplink-Unterstützung in Ihrer Android TV-App implementiert haben, sollten Sie in Ihrem Android TV-Manifest eine ähnliche Definition konfiguriert haben:

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

Nach Entität auf Absender laden

Bei den Absendern können Sie den Deeplink übergeben, indem Sie das entity in den Medien festlegen Informationen zur Ladeanfrage:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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)
<ph type="x-smartling-placeholder">
</ph>
Android
<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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);
<ph type="x-smartling-placeholder">
</ph>
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)
<ph type="x-smartling-placeholder">
</ph>
Web

Chromium-Browserversion erforderlich M87 oder höher.

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

Der Ladebefehl wird über einen Intent mit Ihrem Deeplink und dem Paketnamen gesendet die Sie in der Developer Console definiert haben.

ATV-Anmeldedaten für Absender festlegen

Möglicherweise unterstützen deine Web Receiver App und die Android TV App unterschiedliche Deeplinks und credentials (wenn du beispielsweise die Authentifizierung auf beiden Plattformen unterscheidet. Um dies zu beheben, können Sie entity und credentials für Android TV:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Android
<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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)
<ph type="x-smartling-placeholder">
</ph>
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);
<ph type="x-smartling-placeholder">
</ph>
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)
<ph type="x-smartling-placeholder">
</ph>
Web

Chromium-Browserversion erforderlich M87 oder höher.

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

Wenn die Web Receiver-App gestartet wird, verwendet sie die entity und credentials in der Ladeanforderung. Wenn deine Android TV App jedoch gestartet wird, überschreibt das SDK entity und credentials mit deinem atvEntity und atvCredentials (falls angegeben).

Laden nach Content ID oder MediaQueueData

Wenn du weder entity noch atvEntity, sondern Content ID oder Content-URL in Ihren Medieninformationen oder verwenden Sie die detailliertere Medienlast „Request Data“ (Anfragedaten) müssen Sie den folgenden vordefinierten Intent-Filter hinzufügen: Ihre Android TV App:

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

Auf der Absenderseite haben Sie ähnlich wie beim Laden nach Entität kann eine Ladeanfrage mit Ihren Inhaltsinformationen erstellen und load() aufrufen.

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Android
<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Kotlin
val mediaToLoad = MediaInfo.Builder("some-id").build()
val loadRequest = MediaLoadRequestData.Builder()
    .setMediaInfo(mediaToLoad)
    .setCredentials("user-credentials")
    ...
    .build()
remoteMediaClient.load(loadRequest)
<ph type="x-smartling-placeholder">
</ph>
Java
MediaInfo mediaToLoad =
    new MediaInfo.Builder("some-id").build();
MediaLoadRequestData loadRequest =
    new MediaLoadRequestData.Builder()
        .setMediaInfo(mediaToLoad)
        .setCredentials("user-credentials")
        ...
        .build();
remoteMediaClient.load(loadRequest);
<ph type="x-smartling-placeholder">
</ph>
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)
<ph type="x-smartling-placeholder">
</ph>
Web

Chromium-Browserversion erforderlich M87 oder höher.

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

Lastanfragen verarbeiten

Zum Verarbeiten dieser Ladeanfragen müssen Sie in Ihrer Aktivität die Intents verarbeiten, in den Callbacks für den Aktivitätslebenszyklus:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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.
    ...
  }
}
<ph type="x-smartling-placeholder">
</ph>
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.
    ...
  }
}

Wenn MediaManager erkennt der Intent einen Lade-Intent und extrahiert einen MediaLoadRequestData aus dem Intent und rufen Sie MediaLoadCommandCallback.onLoad() Sie müssen diese Methode überschreiben, um die Ladeanfrage zu verarbeiten. Der Callback muss registriert sein, bevor MediaManager.onNewIntent() aufgerufen wird (wir empfehlen, sich in einer Aktivität oder App onCreate() -Methode).

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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)
  }
<ph type="x-smartling-placeholder">
</ph>
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);
}

Zum Verarbeiten des Lade-Intents können Sie den Intent in die Datenstrukturen parsen haben wir definiert, MediaLoadRequestData für Ladeanfragen).

Unterstützte Medienbefehle

Grundlegende Unterstützung für die Wiedergabesteuerung

Grundlegende Integrationsbefehle enthalten die Befehle, die mit Medien kompatibel sind Sitzung. Diese Befehle werden über Callbacks für Mediensitzungen benachrichtigt. Erforderliche Schritte Registrieren Sie einen Callback für die Mediensitzung, um dies zu unterstützen. bereits).

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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())
<ph type="x-smartling-placeholder">
</ph>
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());

Unterstützung für Cast-Steuerungsbefehle

Einige Cast-Befehle sind in MediaSession, zum Beispiel skipAd() oder setActiveMediaTracks() Außerdem müssen hier einige Befehle für die Wiedergabeliste implementiert werden, da die Wiedergabeliste ist nicht vollständig kompatibel mit der MediaSession-Warteschlange.

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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())
<ph type="x-smartling-placeholder">
</ph>
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());

Unterstützte Medienbefehle angeben

Wie bei Ihrem Cast-Receiver sollte Ihre Android TV App angeben, welche Befehle Sie verwenden möchten. werden unterstützt, sodass Absender bestimmte UI-Steuerelemente aktivieren oder deaktivieren können. Für Befehle, die Teil des MediaSession, geben Sie die Befehle in PlaybackStateCompat Zusätzliche Befehle sollten in der MediaStatusModifier

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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)
<ph type="x-smartling-placeholder">
</ph>
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);

Nicht unterstützte Schaltflächen ausblenden

Wenn die Android TV App nur die grundlegende Mediensteuerung unterstützt, aber Ihr Web Receiver App erweiterte Steuerungsmöglichkeiten unterstützt, sollten Sie darauf achten, dass Ihre Absender-App wenn Sie Inhalte über die Android TV App streamen. Wenn Ihr Android TV-Gerät im Gegensatz zur Web Receiver App kann die Wiedergabegeschwindigkeit nicht geändert werden. sollten Sie die unterstützten Aktionen auf jeder Plattform richtig festlegen und ob die Sender-App die UI korrekt rendert.

MediaStatus ändern

Zur Unterstützung erweiterter Funktionen wie Titel, Anzeigen, Livestreams und Wiedergabelisten Die TV-App muss zusätzliche Informationen bereitstellen, die nicht über MediaSession

Wir stellen die MediaStatusModifier damit Sie dies erreichen können. MediaStatusModifier wird immer auf dem MediaSession, die Sie festgelegt haben CastReceiverContext

Um Inhalte zu erstellen und zu übertragen MediaStatus:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Kotlin
val mediaManager: MediaManager = castReceiverContext.getMediaManager()
val statusModifier: MediaStatusModifier = mediaManager.getMediaStatusModifier()

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

mediaManager.broadcastMediaStatus()
<ph type="x-smartling-placeholder">
</ph>
Java
MediaManager mediaManager = castReceiverContext.getMediaManager();
MediaStatusModifier statusModifier = mediaManager.getMediaStatusModifier();

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

mediaManager.broadcastMediaStatus();

Unsere Clientbibliothek ruft die Basis-MediaStatus von MediaSession ab. In der Android TV-App kann über eine MediaStatus-Modifikator.

Einige Status und Metadaten können sowohl in MediaSession als auch in MediaStatusModifier. Wir empfehlen dringend, sie nur in MediaSession Sie können den Modifikator trotzdem verwenden, um die Zustände in MediaSession: Dies wird nicht empfohlen, da der Status im Modifikator immer haben eine höhere Priorität als die von MediaSession bereitgestellten Werte.

MediaStatus wird vor dem Senden abgefangen

Wie beim Web Receiver SDK, wenn Sie vor dem senden möchten, können Sie eine MediaStatusInterceptor zur Verarbeitung der MediaStatus bis gesendet werden. Wir übergeben eine MediaStatusWriter um die MediaStatus vor dem Versand zu manipulieren.

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Kotlin
mediaManager.setMediaStatusInterceptor(object : MediaStatusInterceptor {
    override fun intercept(mediaStatusWriter: MediaStatusWriter) {
      // Perform customization.
        mediaStatusWriter.setCustomData(JSONObject("{data: \"my Hello\"}"))
    }
})
<ph type="x-smartling-placeholder">
</ph>
Java
mediaManager.setMediaStatusInterceptor(new MediaStatusInterceptor() {
    @Override
    public void intercept(MediaStatusWriter mediaStatusWriter) {
        // Perform customization.
        mediaStatusWriter.setCustomData(new JSONObject("{data: \"my Hello\"}"));
    }
});

Umgang mit Nutzeranmeldedaten

Ihre Android TV-App erlaubt möglicherweise nur bestimmten Nutzern, die App zu starten oder ihr beizutreten Sitzung. Erlauben Sie einem Absender beispielsweise nur in folgenden Fällen das Starten oder die Teilnahme:

  • Die Absender-App ist im selben Konto und Profil wie die ATV-App angemeldet.
  • Die Absender-App ist im selben Konto angemeldet, aber in einem anderen Profil als die ATV-App.

Wenn deine App mehrere oder anonyme Nutzer verarbeiten kann, kannst du zusätzliche um an der ATV-Sitzung teilzunehmen. Wenn der Nutzer Anmeldedaten angibt, wird Ihre ATV-App müssen ihre Anmeldedaten verarbeiten, damit ihr Fortschritt und andere Nutzerdaten ordnungsgemäß erfasst werden.

Wenn Ihre Absender-App in Ihrer Android TV App gestartet oder beigetreten ist, wird Ihre Absender-App die Anmeldedaten bereitstellen, die angeben, wer an der Sitzung teilnimmt.

Bevor ein Absender Ihre Android TV App startet und ihr beitritt, können Sie eine Starten Sie die Prüfung, um zu sehen, ob die Anmeldedaten des Absenders zugelassen sind. Ist dies nicht der Fall, Connect SDK setzt den Web Receiver als Fallback ein.

Anmeldedaten für den Start der Sender-App

Auf der Absenderseite können Sie mit der CredentialsData angeben, wer teilnehmen zu können.

Das credentials ist ein String, der vom Nutzer definiert werden kann, die App verstehen kann. Mit credentialsType wird definiert, auf welcher Plattform CredentialsData stammt von oder kann ein benutzerdefinierter Wert sein. Standardmäßig ist sie festgelegt. an die Plattform, über die es gesendet wird.

Die CredentialsData wird nur bei der Einführung oder beim Zeitpunkt der Teilnahme. Wenn du ihn wieder festlegst, während die Verbindung besteht, wird er nicht an Ihre Android TV-App. Wenn der Absender das Profil wechselt, während eine Verbindung besteht, entweder in der Sitzung bleiben oder SessionManager.endCurrentCastSession(boolean stopCasting) wenn Sie der Meinung sind, dass das neue Profil nicht mit der Sitzung kompatibel ist.

Die CredentialsData für jeden Absender abgerufen werden können, getSenders am CastReceiverContext um die SenderInfo zu erhalten, getCastLaunchRequest(). um die CastLaunchRequest, und dann getCredentialsData()

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Android

Version play-services-cast-framework erforderlich 19.0.0 oder höher.

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Kotlin
CastContext.getSharedInstance().setLaunchCredentialsData(
    CredentialsData.Builder()
        .setCredentials("{\"userId\": \"abc\"}")
        .build()
)
<ph type="x-smartling-placeholder">
</ph>
Java
CastContext.getSharedInstance().setLaunchCredentialsData(
    new CredentialsData.Builder()
        .setCredentials("{\"userId\": \"abc\"}")
        .build());
<ph type="x-smartling-placeholder">
</ph>
iOS

Erfordert google-cast-sdk Version v4.8.3 oder höher liegen.

Kann jederzeit aufgerufen werden, nachdem die Optionen festgelegt wurden: GCKCastContext.setSharedInstanceWith(options)

GCKCastContext.sharedInstance().setLaunch(
    GCKCredentialsData(credentials: "{\"userId\": \"abc\"}")
<ph type="x-smartling-placeholder">
</ph>
Web

Chromium-Browserversion erforderlich M87 oder höher.

Kann jederzeit aufgerufen werden, nachdem die Optionen festgelegt wurden: cast.framework.CastContext.getInstance().setOptions(options);

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

ATV-Startanfrageprüfung implementieren

Die CredentialsData wird an Ihre Android TV App übergeben, wenn ein Absender versucht, einen Dienst zu starten oder ihm beizutreten. Sie können eine LaunchRequestChecker um diese Anfrage zuzulassen oder abzulehnen.

Wenn eine Anfrage abgelehnt wird, wird Web Receiver nicht gestartet, sondern geladen nativ in die ATV-App integriert. Sie sollten eine Anfrage ablehnen, wenn Ihr ATV die den Nutzer zum Start oder zur Teilnahme auffordern. Beispiel: Eine andere Benutzer ist in der ATV-App angemeldet als fordert und Ihre App kann nicht wenn es um das Wechseln der Anmeldedaten geht oder im Moment kein Nutzer im ATV-App

Wenn eine Anfrage zulässig ist, wird die ATV-App gestartet. Sie können dies anpassen je nachdem, ob Ihre App das Senden von Ladeanfragen unterstützt, nicht in der ATV-App angemeldet ist oder die Nutzer nicht übereinstimmen. Dieses Verhalten ist vollständig veränderbar in LaunchRequestChecker.

Erstellen Sie eine Klasse, in der die CastReceiverOptions.LaunchRequestChecker Schnittstelle:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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.
}
<ph type="x-smartling-placeholder">
</ph>
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;
}

Legen Sie ihn dann in Ihrem ReceiverOptionsProvider:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Kotlin
class MyReceiverOptionsProvider : ReceiverOptionsProvider {
  override fun getOptions(context: Context?): CastReceiverOptions {
    return CastReceiverOptions.Builder(context)
        ...
        .setLaunchRequestChecker(MyLaunchRequestChecker())
        .build()
  }
}
<ph type="x-smartling-placeholder">
</ph>
Java
public class MyReceiverOptionsProvider implements ReceiverOptionsProvider {
  @Override
  public CastReceiverOptions getOptions(Context context) {
    return new CastReceiverOptions.Builder(context)
        ...
        .setLaunchRequestChecker(new MyLaunchRequestChecker())
        .build();
  }
}

true wird geklärt in: LaunchRequestChecker startet die ATV-App und false startet die Web Receiver-App.

Senden und Benutzerdefinierte Nachrichten erhalten

Mit dem Cast-Protokoll können Sie benutzerdefinierte Nachrichtenstrings zwischen Absendern und in der Empfangsanwendung. Sie müssen einen Namespace (Kanal) registrieren, um Nachrichten senden, bevor Sie Ihre CastReceiverContext

Android TV – Benutzerdefinierten Namespace angeben

Sie müssen Ihre unterstützten Namespaces in Ihrem CastReceiverOptions während der Einrichtung:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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()
  }
}
<ph type="x-smartling-placeholder">
</ph>
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: Nachrichten senden

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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)
<ph type="x-smartling-placeholder">
</ph>
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: Benutzerdefinierte Namespace-Nachrichten empfangen

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
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());
<ph type="x-smartling-placeholder">
</ph>
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());