Ab Android 8.0 (API-Ebene 26) können Aktivitäten in Android im Bild-im-Bild-Modus (PiP) gestartet werden. Der PiP-Modus ist ein spezieller Multifenstermodus, der hauptsächlich für die Videowiedergabe verwendet wird. Nutzer können sich ein Video in einem kleinen Fenster ansehen, das in einer Ecke des Bildschirms angepinnt ist, während sie zwischen Apps wechseln oder Inhalte auf dem Hauptbildschirm durchsuchen.
BiB nutzt die in Android 7.0 verfügbaren Mehrfenster-APIs, um das angepinnte Video-Overlay-Fenster bereitzustellen. Wenn Sie Ihrer App PiP hinzufügen möchten, müssen Sie die Aktivitäten registrieren, die PiP unterstützen, die Aktivität bei Bedarf in den PiP-Modus umschalten und dafür sorgen, dass die UI-Elemente ausgeblendet sind und die Videowiedergabe fortgesetzt wird, wenn die Aktivität im PiP-Modus ist.
Das PiP-Fenster wird in der obersten Ebene des Bildschirms in einer vom System ausgewählten Ecke angezeigt.
PiP wird auch auf kompatiblen Android TV-Geräten mit Android 14 (API-Level 34) oder höher unterstützt. Es gibt zwar viele Ähnlichkeiten, aber bei der Verwendung von PiP auf dem Fernseher gibt es zusätzliche Aspekte zu beachten.
Interaktionsmöglichkeiten der Nutzer mit dem PiP-Fenster
Nutzer können das PiP-Fenster an eine andere Stelle ziehen. Ab Android 12 haben Nutzer außerdem folgende Möglichkeiten:
Tippen Sie einmal auf das Fenster, um eine Vollbildschaltfläche, eine Schaltfläche zum Schließen, eine Schaltfläche für die Einstellungen und benutzerdefinierte Aktionen Ihrer App (z. B. Wiedergabesteuerungen) aufzurufen.
Tippe doppelt auf das Fenster, um zwischen der aktuellen BiB-Größe und der maximalen oder minimalen BiB-Größe zu wechseln. Wenn du beispielsweise doppelt auf ein maximiertes Fenster tippst, wird es minimiert. Umgekehrt gilt das ebenfalls.
Verschieben Sie das Fenster, indem Sie es an den linken oder rechten Rand ziehen. Wenn Sie das Fenster wieder einblenden möchten, tippen Sie entweder auf den sichtbaren Teil des minimierten Fensters oder ziehen Sie es heraus.
Ändern Sie die Größe des BiB-Fensters, indem Sie zum Zoomen die Finger auseinander- und zusammenziehen.
Ihre App steuert, wann die aktuelle Aktivität in den PiP-Modus wechselt. Hier einige Beispiele:
Eine Aktivität kann in den PiP-Modus wechseln, wenn der Nutzer auf die Schaltfläche „Startseite“ tippt oder zum Startbildschirm wischt. So werden in Google Maps weiterhin Wegbeschreibungen angezeigt, während der Nutzer gleichzeitig eine andere Aktivität ausführt.
Deine App kann ein Video in den BiB-Modus versetzen, wenn der Nutzer vom Video zurückkehrt, um andere Inhalte zu durchsuchen.
Ihre App kann ein Video in den PiP-Modus umschalten, während sich ein Nutzer das Ende einer Folge ansieht. Der Hauptbildschirm zeigt Werbe- oder zusammenfassende Informationen zur nächsten Folge der Serie an.
Ihre App kann Nutzern die Möglichkeit bieten, während der Wiedergabe eines Videos zusätzliche Inhalte der Wiedergabeliste hinzuzufügen. Das Video wird im PiP-Modus fortgesetzt, während auf dem Hauptbildschirm eine Aktivität zur Inhaltsauswahl angezeigt wird.
BiB-Unterstützung deklarieren
Standardmäßig unterstützt das System PiP für Apps nicht automatisch. Wenn Sie PiP in Ihrer App unterstützen möchten, registrieren Sie Ihre Videoaktivität in Ihrem Manifest, indem Sie android:supportsPictureInPicture
auf true
festlegen. Gib außerdem an, dass deine Aktivität Layout-Konfigurationsänderungen verarbeitet, sodass sie nicht neu gestartet wird, wenn Layoutänderungen während Wechsel des BiB-Modus vorgenommen werden.
<activity android:name="VideoActivity"
android:supportsPictureInPicture="true"
android:configChanges=
"screenSize|smallestScreenSize|screenLayout|orientation"
...
Aktivitäten auf BiB umstellen
Ab Android 12 können Sie Ihre Aktivität in den PiP-Modus umschalten, indem Sie das Flag setAutoEnterEnabled
auf true
setzen. Bei dieser Einstellung wechselt eine Aktivität bei Bedarf automatisch in den PiP-Modus, ohne dass onUserLeaveHint
enterPictureInPictureMode()
explizit aufgerufen werden muss. Außerdem sind die Übergänge so viel flüssiger. Weitere Informationen finden Sie unter Übergangsanimationen zum PiP-Modus über die Touchbedienung optimieren.
Wenn deine App auf Android 11 oder niedriger ausgerichtet ist, muss eine Aktivität enterPictureInPictureMode()
aufrufen, um in den BiB-Modus zu wechseln. Mit dem folgenden Code wird beispielsweise eine Aktivität in den BiB-Modus versetzt, wenn der Nutzer auf eine spezielle Schaltfläche in der Benutzeroberfläche der App klickt:
override fun onActionClicked(action: Action) { if (action.id.toInt() == R.id.lb_control_picture_in_picture) { activity?.enterPictureInPictureMode() return } }
@Override public void onActionClicked(Action action) { if (action.getId() == R.id.lb_control_picture_in_picture) { getActivity().enterPictureInPictureMode(); return; } ... }
Möglicherweise möchten Sie eine Logik einbinden, die eine Aktivität in den BiB-Modus verwandelt, anstatt in den Hintergrund zu gehen. Google Maps wechselt beispielsweise in den BiB-Modus, wenn der Nutzer während der Navigation in der App die Startbildschirmtaste oder die Schaltfläche „Letzte“ drückt. Sie können diesen Fall abfangen, indem Sie onUserLeaveHint()
überschreiben:
override fun onUserLeaveHint() { if (iWantToBeInPipModeNow()) { enterPictureInPictureMode() } }
@Override public void onUserLeaveHint () { if (iWantToBeInPipModeNow()) { enterPictureInPictureMode(); } }
Empfohlen: Nutzern eine ausgefeilte BiB-Umstellung anbieten
Bei Android 12 wurden die animierten Übergänge zwischen Vollbild- und BiB-Fenstern deutlich verbessert. Wir empfehlen Ihnen dringend, alle erforderlichen Änderungen vorzunehmen. Anschließend werden diese Änderungen automatisch auf große Bildschirme wie faltbare Smartphones und Tablets skaliert, ohne dass Sie weitere Maßnahmen ergreifen müssen.
Wenn deine App keine entsprechenden Updates enthält, funktionieren BiB-Übergänge weiterhin, die Animationen sind jedoch weniger ausgefeilt. Wenn du beispielsweise vom Vollbildmodus zum PiP-Modus wechselst, kann es passieren, dass das PiP-Fenster während des Wechsels verschwindet und erst nach Abschluss des Wechsels wieder erscheint.
Diese Änderungen beinhalten Folgendes.
- Der Wechsel in den PiP-Modus über die Bedienung per Geste ist jetzt flüssiger.
- Richtige
sourceRectHint
zum Aufrufen und Beenden des BiB-Modus festlegen - Automatische Größenanpassung für Inhalte ohne Video deaktivieren
Informationen zur Aktivierung eines ausgefeilten Übergangs finden Sie im Android Kotlin PictureInPicture-Beispiel.
Einfacher Wechsel zum BiB-Modus von der Bedienung über Gesten
Ab Android 12 sorgt das Flag setAutoEnterEnabled
für eine viel flüssigere Animation beim Wechsel zu Videoinhalten im PiP-Modus über die Gestennavigation, z. B. wenn Sie vom Vollbildmodus zum Startbildschirm wischen.
Führen Sie die folgenden Schritte aus, um diese Änderung vorzunehmen. Sehen Sie sich als Referenz dieses Beispiel an:
Verwenden Sie
setAutoEnterEnabled
, umPictureInPictureParams.Builder
zu erstellen:setPictureInPictureParams(PictureInPictureParams.Builder() .setAspectRatio(aspectRatio) .setSourceRectHint(sourceRectHint) .setAutoEnterEnabled(true) .build())
setPictureInPictureParams(new PictureInPictureParams.Builder() .setAspectRatio(aspectRatio) .setSourceRectHint(sourceRectHint) .setAutoEnterEnabled(true) .build());
Rufe
setPictureInPictureParams
mit dem aktuellenPictureInPictureParams
frühzeitig auf. Die App wartet nicht auf denonUserLeaveHint
-Callback, wie es bei Android 11 der Fall gewesen wäre.Du kannst
setPictureInPictureParams
beispielsweise bei der allerersten Wiedergabe und bei jeder weiteren Wiedergabe aufrufen, wenn sich das Seitenverhältnis ändert.Rufen Sie
setAutoEnterEnabled(false)
auf, aber nur bei Bedarf. So möchtest du beispielsweise wahrscheinlich nicht in den Bild-im-Bild-Modus wechseln, wenn die aktuelle Wiedergabe pausiert ist.
Richtige sourceRectHint
zum Aufrufen und Beenden des BiB-Modus festlegen
Seit der Einführung von BiB in Android 8.0 gibt setSourceRectHint
an, welcher Bereich der Aktivität nach dem Wechsel in den Bild-im-Bild-Modus sichtbar ist, z. B. die Videowiedergabegrenzen in einem Videoplayer.
Unter Android 12 verwendet das System sourceRectHint
, um sowohl beim Starten als auch beim Beenden des BiB-Modus eine viel flüssigere Animation zu implementieren.
So legen Sie sourceRectHint
richtig für den Wechsel in den und den Ausstieg aus dem PiP-Modus fest:
Erstellen Sie
PictureInPictureParams
mit den richtigen Grenzen alssourceRectHint
. Wir empfehlen außerdem, dem Videoplayer einen Listener für Layoutänderungen hinzuzufügen:val mOnLayoutChangeListener = OnLayoutChangeListener { v: View?, oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int, newLeft: Int, newTop: Int, newRight: Int, newBottom: Int -> val sourceRectHint = Rect() mYourVideoView.getGlobalVisibleRect(sourceRectHint) val builder = PictureInPictureParams.Builder() .setSourceRectHint(sourceRectHint) setPictureInPictureParams(builder.build()) } mYourVideoView.addOnLayoutChangeListener(mOnLayoutChangeListener)
private final View.OnLayoutChangeListener mOnLayoutChangeListener = (v, oldLeft, oldTop, oldRight, oldBottom, newLeft, newTop, newRight, newBottom) -> { final Rect sourceRectHint = new Rect(); mYourVideoView.getGlobalVisibleRect(sourceRectHint); final PictureInPictureParams.Builder builder = new PictureInPictureParams.Builder() .setSourceRectHint(sourceRectHint); setPictureInPictureParams(builder.build()); }; mYourVideoView.addOnLayoutChangeListener(mOnLayoutChangeListener);
Aktualisieren Sie bei Bedarf die
sourceRectHint
, bevor das System den Exit-Übergang startet. Wenn das System den PiP-Modus beenden wird, wird die Ansichtshierarchie der Aktivität in der Zielkonfiguration (z. B. Vollbild) angeordnet. Die App kann einen Listener für Layoutänderungen an die Stamm- oder Zielansicht (z. B. die Videoplayeransicht) anhängen, um das Ereignis zu erkennen undsourceRectHint
vor Beginn der Animation zu aktualisieren.// Listener is called immediately after the user exits PiP but before animating. playerView.addOnLayoutChangeListener { _, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom -> if (left != oldLeft || right != oldRight || top != oldTop || bottom != oldBottom) { // The playerView's bounds changed, update the source hint rect to // reflect its new bounds. val sourceRectHint = Rect() playerView.getGlobalVisibleRect(sourceRectHint) setPictureInPictureParams( PictureInPictureParams.Builder() .setSourceRectHint(sourceRectHint) .build() ) } }
// Listener is called right after the user exits PiP but before animating. playerView.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { if (left != oldLeft || right != oldRight || top != oldTop || bottom != oldBottom) { // The playerView's bounds changed, update the source hint rect to // reflect its new bounds. final Rect sourceRectHint = new Rect(); playerView.getGlobalVisibleRect(sourceRectHint); setPictureInPictureParams( new PictureInPictureParams.Builder() .setSourceRectHint(sourceRectHint) .build()); } });
Nahtlose Größenanpassung für Inhalte, die keine Videos sind, deaktivieren
In Android 12 wird das Flag setSeamlessResizeEnabled
hinzugefügt, das eine viel flüssigere Cross-Fading-Animation beim Ändern der Größe von nicht videobasierten Inhalten im PiP-Fenster ermöglicht. Bisher konnten durch die Größenanpassung von Inhalten ohne Videos in einem BiB-Fenster zu verwirrenden visuellen Artefakten geführt werden.
So deaktivieren Sie die nahtlose Größenanpassung für Inhalte, die keine Videos sind:
setPictureInPictureParams(PictureInPictureParams.Builder() .setSeamlessResizeEnabled(false) .build())
setPictureInPictureParams(new PictureInPictureParams.Builder() .setSeamlessResizeEnabled(false) .build());
Benutzeroberfläche während der Wiedergabe im Bild-im-Bild-Modus
Wenn die Aktivität in den Bild-im-Bild-Modus wechselt oder ihn verlässt, ruft das System Activity.onPictureInPictureModeChanged()
oder Fragment.onPictureInPictureModeChanged()
auf.
Android 15 führt Änderungen ein, die für einen noch reibungslosen Übergang im BiB-Modus sorgen. Das ist für Apps mit UI-Elementen vor der Haupt-UI von Vorteil, die in PiP angezeigt werden.
Entwickler verwenden den Rückruf onPictureInPictureModeChanged()
, um eine Logik zu definieren, mit der die Sichtbarkeit der überlagerten UI-Elemente umgeschaltet wird.
Dieser Callback wird ausgelöst, wenn die BiB-Eingabe- oder -Exit-Animation abgeschlossen ist.
Ab Android 15 enthält die Klasse PictureInPictureUiState
einen neuen Status.
Mit diesem neuen UI-Status beobachten Apps, die auf Android 15 ausgerichtet sind, den Activity#onPictureInPictureUiStateChanged()
-Callback mit isTransitioningToPip()
, sobald die BiB-Animation gestartet wird.
Es gibt viele UI-Elemente, die für die App im BiB-Modus nicht relevant sind, z. B. Ansichten oder Layout, die Informationen wie Vorschläge, anstehende Videos, Bewertungen und Titel enthalten. Wenn die App in den BiB-Modus wechselt, verwende den onPictureInPictureUiStateChanged()
-Callback, um diese UI-Elemente auszublenden. Wenn die App über das BiB-Fenster in den Vollbildmodus wechselt, verwende den Callback onPictureInPictureModeChanged()
, um diese Elemente einzublenden, wie in den folgenden Beispielen gezeigt:
override fun onPictureInPictureUiStateChanged(pipState: PictureInPictureUiState) { if (pipState.isTransitioningToPip()) { // Hide UI elements. } }
@Override public void onPictureInPictureUiStateChanged(PictureInPictureUiState pipState) { if (pipState.isTransitioningToPip()) { // Hide UI elements. } }
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) { if (isInPictureInPictureMode) { // Unhide UI elements. } }
@Override public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) { if (isInPictureInPictureMode) { // Unhide UI elements. } }
Diese schnelle Ein/Aus-Schaltfläche für die Sichtbarkeit irrelevanter UI-Elemente (für ein BiB-Fenster) sorgt für eine flüssigere und flimmernde BiB-Eingabe bei der Animation.
Überschreibe diese Callbacks, um die UI-Elemente der Aktivität neu zu zeichnen. Im BiB-Modus wird deine Aktivität in einem kleinen Fenster angezeigt. Nutzer können nicht mit den UI-Elementen Ihrer App interagieren, wenn sich die App im BiB-Modus befindet und die Details kleiner UI-Elemente möglicherweise schwer zu sehen sind. Videowiedergaben mit minimaler Benutzeroberfläche bieten die beste Nutzererfahrung.
Wenn Ihre App benutzerdefinierte Aktionen für PiP bereitstellen muss, lesen Sie den Abschnitt Steuerelemente hinzufügen auf dieser Seite. Entfernen Sie andere UI-Elemente, bevor die Aktivität in den PiP-Modus wechselt, und stellen Sie sie wieder her, wenn die Aktivität wieder im Vollbildmodus angezeigt wird.
Steuerelemente hinzufügen
Im BiB-Fenster können Steuerelemente angezeigt werden, wenn der Nutzer das Fenster des Fensters öffnet. Dazu kann er auf einem Mobilgerät auf das Fenster tippen oder das Menü auf der Fernbedienung des Fernsehers auswählen.
Wenn für eine App eine aktive Mediensitzung vorliegt, werden die Steuerelemente „Wiedergabe“, „Pause“, „Weiter“ und „Zurück“ angezeigt.
Sie können auch benutzerdefinierte Aktionen explizit angeben, indem Sie PictureInPictureParams
mit PictureInPictureParams.Builder.setActions()
erstellen, bevor Sie den PiP-Modus aktivieren, und die Parameter übergeben, wenn Sie den PiP-Modus mit enterPictureInPictureMode(android.app.PictureInPictureParams)
oder setPictureInPictureParams(android.app.PictureInPictureParams)
aktivieren.
Sei vorsichtig. Wenn Sie mehr als getMaxNumPictureInPictureActions()
hinzufügen, erhalten Sie nur die maximale Anzahl.
Videowiedergabe in der Bild-im-Bild-Funktion fortsetzen
Wenn die Aktivität in den PiP-Modus wechselt, setzt das System die Aktivität in den Pausierstatus und ruft die Methode onPause()
der Aktivität auf. Die Videowiedergabe sollte nicht pausiert und stattdessen fortgesetzt werden, wenn die Aktivität beim Wechsel in den BiB-Modus pausiert wird.
Unter Android 7.0 und höher sollten Sie die Videowiedergabe pausieren und fortsetzen, wenn das System onStop()
und onStart()
für Ihre Aktivität aufruft. So musst du nicht prüfen, ob sich deine App in onPause()
im BiB-Modus befindet, und die Wiedergabe explizit fortsetzen.
Wenn du das Flag setAutoEnterEnabled
nicht auf true
gesetzt hast und die Wiedergabe in deiner onPause()
-Implementierung pausieren musst, überprüfe den BiB-Modus, indem du isInPictureInPictureMode()
aufrufst und die Wiedergabe entsprechend anpasst. Beispiel:
override fun onPause() { super.onPause() // If called while in PiP mode, do not pause playback. if (isInPictureInPictureMode) { // Continue playback. } else { // Use existing playback logic for paused activity behavior. } }
@Override public void onPause() { // If called while in PiP mode, do not pause playback. if (isInPictureInPictureMode()) { // Continue playback. ... } else { // Use existing playback logic for paused activity behavior. ... } }
Wenn Ihre Aktivität aus dem BiB-Modus zurück in den Vollbildmodus wechselt, setzt das System die Aktivität fort und ruft die Methode onResume()
auf.
Einzelne Wiedergabeaktivität für BiB verwenden
In Ihrer App kann ein Nutzer ein neues Video auswählen, während er auf dem Hauptbildschirm nach Inhalten sucht und eine Videowiedergabe im Bild-im-Bild-Modus läuft. Spiele das neue Video in der bestehenden Wiedergabeaktivität im Vollbildmodus ab, anstatt eine neue Aktivität zu starten, die den Nutzer verwirren könnte.
Damit für Videowiedergabeanfragen immer dieselbe Aktivität verwendet wird und der PiP-Modus bei Bedarf aktiviert oder deaktiviert wird, legen Sie in Ihrem Manifest die android:launchMode
der Aktivität auf singleTask
fest:
<activity android:name="VideoActivity"
...
android:supportsPictureInPicture="true"
android:launchMode="singleTask"
...
Überschreiben Sie in Ihrer Aktivität onNewIntent()
und verarbeiten Sie das neue Video. Beenden Sie bei Bedarf die Wiedergabe des vorhandenen Videos.
Best Practices
Auf Geräten mit wenig RAM ist PiP möglicherweise deaktiviert. Bevor deine Anwendung BiB verwendet, prüfe durch Aufrufen von hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)
, ob sie verfügbar ist.
Der Bild-im-Bild-Modus ist für Aktivitäten gedacht, bei denen Videos im Vollbildmodus abgespielt werden. Wenn du in den BiB-Modus wechselst, solltest du nur Videoinhalte zeigen. Sie können erfassen, wann Ihre Aktivität in den PiP-Modus wechselt, und UI-Elemente ausblenden, wie unter Behandlung der Benutzeroberfläche während des PiP-Modus beschrieben.
Wenn eine Aktivität im PiP-Modus ist, erhält sie standardmäßig nicht den Eingabefokus. Wenn du Eingabeereignisse im PiP-Modus erhalten möchtest, verwende MediaSession.setCallback()
.
Weitere Informationen zur Verwendung von setCallback()
findest du unter Now Playing-Card anzeigen.
Wenn sich deine App im BiB-Modus befindet, kann die Videowiedergabe im BiB-Fenster eine andere App stören, z. B. eine Musikplayer-App oder eine Sprachsuche-App. Um dies zu vermeiden, kannst du den Audiofokus zu Beginn der Videowiedergabe anfordern und Benachrichtigungen zu Änderungen des Audiofokus verarbeiten, wie unter Audiofokus verwalten beschrieben. Wenn Sie im PiP-Modus eine Benachrichtigung zum Verlust des Audiofokus erhalten, pausieren oder beenden Sie die Videowiedergabe.
Wenn in deiner App BiB gestartet wird, wird nur die oberste Aktivität als Bild im Bild aktiviert. In einigen Situationen, z. B. auf Geräten mit Mehrfenstermodus, ist es möglich, dass die unten stehende Aktivität jetzt zusammen mit der BiB-Aktivität wieder sichtbar wird. Du solltest diesen Fall entsprechend behandeln, einschließlich der Aktivität unten, bei der du einen Rückruf von onResume()
oder onPause()
erhältst. Es ist auch möglich, dass der Nutzer mit der Aktivität interagiert. Wenn du beispielsweise eine Videolistenaktivität und die Videowiedergabe im BiB-Modus siehst, kann der Nutzer ein neues Video aus der Liste auswählen und die BiB-Aktivität wird entsprechend aktualisiert.
Zusätzlicher Beispielcode
Informationen zum Herunterladen einer in Kotlin geschriebenen Beispiel-App finden Sie unter Android PictureInPicture Sample (Kotlin).