Android 14 (API-Level 34) führt einige Verbesserungen an den Bild-im-Bild-APIs (PiP) ein, um Multitasking zu ermöglichen. Die Unterstützung von PiP wurde zwar in Android 8.0 (API-Ebene 26) eingeführt, aber nicht umfassend auf Android TV unterstützt und vor Android 13 überhaupt nicht auf Google TV. Beim Multitasking auf dem Fernseher wird der Bild-im-Bild-Modus verwendet, damit zwei separate Apps gleichzeitig auf dem Bildschirm angezeigt werden können: eine im Vollbildmodus und eine im Bild-im-Bild-Modus. Für Apps, die in einem dieser Modi ausgeführt werden, gelten unterschiedliche Anforderungen.
Standardmäßig wird die App im Bild-im-Bild-Modus über die App im Vollbildmodus gelegt. Das entspricht dem Standardverhalten der Android-Funktion „Bild im Bild“.
Wenn Sie Multitasking einbinden, müssen Sie die Nutzungsarten Ihrer Anwendung gemäß den Qualitätsrichtlinien für TV-Apps angeben.
App im PiP-Modus ausführen
Auf Fernsehern mit Android 14 (API-Level 34) oder höher können Sie Ihre App im PiP-Modus ausführen, indem Sie enterPictureInPictureMode()
aufrufen. Fernseher mit älteren Android-Versionen unterstützen den PiP-Modus nicht.
Hier ist ein Beispiel für die Implementierung der Logik einer Schaltfläche, um den PiP-Modus aufzurufen:
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 das Seitenverhältnis des PiP-Modus so festgelegt, dass es mit dem Seitenverhältnis des wiedergegebenen Videos übereinstimmt.
Fügen Sie einen Titel und einen Untertitel hinzu, um den Nutzern zu vermitteln, wozu dieser PIP im Allgemeinen verwendet wird.
Neben Apps laufen, die im PiP-Modus ausgeführt werden
Wenn Ihre App im Vollbildmodus ausgeführt wird, muss sie sich möglicherweise an andere Apps anpassen, die im PiP-Modus ausgeführt werden.
APIs für die Funktion „Bitte nicht stören“
In einigen Fällen kann die PiP-App wichtige UI-Komponenten in der Vollbild-App überlagern. Um dies zu vermeiden, gibt es APIs, mit denen Apps kritische UI-Komponenten identifizieren können, die nicht überlagert werden sollten. Das System versucht, die Anfragen zu erfüllen, um diese Komponenten nicht zu verdecken, indem es das PiP-Fenster neu positioniert.
Wenn Sie angeben möchten, dass eine Ansicht nicht überlagert werden soll, verwenden Sie preferKeepClear
in Ihrem XML-Layout, 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"/>
Du kannst das auch programmatisch mit 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); }
Manchmal müssen Sie nicht die gesamte View
freihalten, sondern nur einen Teil davon. Mit setPreferKeepClearRects()
können Sie Bereiche des View
angeben, die nicht überlagert werden sollen. UIs, die View
nicht nativ verwenden, z. B. Flutter, Jetpack Compose und WebView, können Unterabschnitte haben, in denen Bereiche frei bleiben müssen. Diese API kann für diese Fälle verwendet werden.
Nutzungstypen
Ihre App muss ein Metadatenwertattribut von com.google.android.tv.pip.category
deklarieren, das dem primären oder den primären Verwendungstypen für den Bild-in-Bild-Modus entspricht. Für jedes <activity>
, für das android:supportsPictureInPicture="true"
festgelegt wurde, muss dieses Attribut mit einem relevanten Wert aus der folgenden Tabelle deklariert werden.
Nutzungsarten, die in keine dieser Kategorien fallen, insbesondere die Wiedergabe von Medieninhalten, sind im Bild-im-Bild-Modus auf dem Fernseher nicht zulässig.
Wert | Beschreibung |
---|---|
„communication “ |
Anwendungsfälle für die Kommunikation, z. B. Video- oder Sprachanrufe |
„smartHome “ |
Smart-Home-Integrationen wie verbundene Türklingeln oder Babyfone |
„health “ |
Gesundheitsbezogene Anwendungsfälle wie Fitness-Tracking oder Gesundheitsüberwachung |
„ticker “ |
Anwendungsfälle für Ticker, z. B. Live-Sportergebnisse oder Nachrichten- und Aktienticker. |
Mehrere Werte werden durch einen vertikalen Strich (|
) getrennt. Beispiel:
<meta-data android:name="com.google.android.tv.pip.category" android:value="smartHome|health" />