Multitasking auf dem Fernseher

Unter Android 14 (API-Level 34) wurden einige Verbesserungen an den Bild im Bild-APIs (BiB) eingeführt, um Multitasking zu ermöglichen. BiB wurde zwar in Android 8.0 (API-Level 26) eingeführt, wurde aber vor Android 13 weder von Android TV noch von Google TV unterstützt. Beim Multitasking auf Fernsehern wird der BiB-Modus verwendet, damit zwei separate Apps auf dem Bildschirm nebeneinander existieren können: eine im Vollbildmodus und eine zweite im BiB-Modus. Für Anwendungen, die in einem dieser Modi ausgeführt werden, gelten andere Anforderungen.

Standardmäßig überlagert die BiB-App die Vollbild-App. Das funktioniert ähnlich wie das standardmäßige Bild-im-Bild-Verhalten von Android.

Bei der Integration von Multitasking muss deine App die Nutzungsarten gemäß den Qualitätsrichtlinien für TV-Apps deklarieren.

App im BiB-Modus ausführen

Auf Fernsehern mit Android 14 (API-Level 34) oder höher kannst du deine App im BiB-Modus ausführen, indem du enterPictureInPictureMode() aufrufst. Auf Fernsehern mit älteren Android-Versionen wird der BiB-Modus nicht unterstützt.

Hier ist ein Beispiel für die Implementierung der Logik einer Schaltfläche zum Aufrufen des BiB-Modus:

Kotlin

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    pictureInPictureButton.visibility =
        if (requireActivity().packageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) {
            pictureInPictureButton.setOnClickListener {
                val aspectRatio = Rational(view.width, view.height)
                val params = PictureInPictureParams.Builder()
                    .setAspectRatio(aspectRatio)
                    .build()
                val result = requireActivity().enterPictureInPictureMode(params)
            }
            View.VISIBLE
        } else {
            View.GONE
        }
}

Java

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    if (requireActivity().getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) {
        pictureInPictureButton.setVisibility(View.VISIBLE);
        pictureInPictureButton.setOnClickListener(v -> {
            Rational aspectRatio = new Rational(view.getWidth(), view.getHeight());
            PictureInPictureParams params = new PictureInPictureParams.Builder()
                    .setAspectRatio(aspectRatio)
                    .setTitle("My Streaming App")
                    .setSubtitle("My On-Demand Content")
                    .build();
            Boolean result = requireActivity().enterPictureInPictureMode(params);
        });
    } else {
        pictureInPictureButton.setVisibility(View.GONE);
    }
}

Die Aktion wird nur hinzugefügt, wenn das Gerät die Systemfunktion FEATURE_PICTURE_IN_PICTURE hat. Wenn die Aktion ausgelöst wird, wird außerdem das Seitenverhältnis des BiB-Modus so festgelegt, dass es dem Seitenverhältnis des wiedergegebenen Videos entspricht.

Füge einen Titel und einen Untertitel hinzu, um dem Nutzer Informationen darüber zu geben, wofür diese PIP im Allgemeinen verwendet wird.

Gleichzeitige Verwendung mit Apps, die im BiB-Modus ausgeführt werden

Wenn deine App als Vollbild-App ausgeführt wird, muss sie möglicherweise an andere Apps angepasst werden, die im BiB-Modus ausgeführt werden.

Klare APIs

In einigen Fällen kann die BiB-App wichtige UI-Komponenten innerhalb der Vollbild-App überlagern. Um dies zu vermeiden, gibt es klare APIs, mit denen Apps kritische UI-Komponenten identifizieren können, die nicht eingeblendet werden sollten. Durch eine Neupositionierung des BiB-Fensters versucht das System, die Anfragen zu berücksichtigen, um diese Komponenten nicht abzudecken.

Klarer Zugriff

Um anzugeben, dass eine Ansicht nicht eingeblendet werden soll, verwenden Sie in Ihrem XML-Layout preferKeepClear wie im folgenden Beispiel:

<TextView
    android:id="@+id/important_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:preferKeepClear="true"
    android:text="@string/app_name"/>

Sie können dies auch programmatisch mithilfe von setPreferKeepClear() tun:

Kotlin

private lateinit var binding: MyLayoutBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    binding = MyLayoutBinding.inflate(layoutInflater)
    setContentView(binding.root)
    binding.importantText.isPreferKeepClear = true
}

Java

private MyLayoutBinding binding;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    binding = MyLayoutBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());
    binding.importantText.setPreferKeepClear(true);
}

Es kann vorkommen, dass nicht ein gesamtes View, sondern nur ein Teil davon leer sein muss. Mit setPreferKeepClearRects() können Regionen der View angegeben werden, die nicht eingeblendet werden sollen. UIs, in denen Views nicht nativ verwendet werden, wie Flutter, Jetpack Compose und WebView, haben möglicherweise Unterabschnitte, für die Regionen frei bleiben müssen. Diese API kann in diesen Fällen verwendet werden.

Nutzungstypen

In deiner App muss ein Meta-Datenwertattribut mit com.google.android.tv.pip.category deklariert werden, das der primären Nutzungstyp für den Bild-im-Bild-Modus entspricht. Jede <activity>, für die android:supportsPictureInPicture="true" festgelegt ist, sollte dieses Attribut mit einem relevanten Wert aus der folgenden Tabelle deklarieren.

Nutzungstypen, die in keine dieser Kategorien fallen, insbesondere die Wiedergabe von Medieninhalten, sind im Bild-im-Bild-Modus auf Fernsehern nicht erlaubt.

Antwort Beschreibung
communication Kommunikationsanwendungsfälle wie Video- oder Sprachanrufe
smartHome Smart-Home-Integrationen wie verbundene Türklingeln oder Babyfone
health Gesundheitsbezogene Anwendungsfälle wie Fitness-Tracking oder Gesundheitsüberwachung
ticker Ticker-Anwendungsfälle wie Live-Sportergebnisse oder Nachrichten und Börsenticker.

Mehrere Werte werden durch einen vertikalen Strich (|) getrennt. Beispiel:

<meta-data android:name="com.google.android.tv.pip.category" android:value="smartHome|health" />