Bild im Bild (BiB) verwenden

Compose ausprobieren
Jetpack Compose ist das empfohlene UI-Toolkit für Android. Informationen zum Unterstützen des Bild‑im‑Bild-Modus in Compose

Ab Android 8.0 (API-Level 26) können Aktivitäten im Bild-im-Bild-Modus (BiB) gestartet werden. Der Bild-im-Bild-Modus ist ein spezieller Multifenstermodus, der für die Videowiedergabe, Videoanrufe und die Navigation verwendet wird. So kann der Nutzer das vorhandene Aktivitätsfenster an einer Ecke des Bildschirms anpinnen, während er zwischen Apps wechselt oder sich Inhalte auf dem Hauptbildschirm ansieht.

Für das Overlay-Fenster mit dem angepinnten Video wird der Mehrfenstermodus genutzt, der in Android 7.0 eingeführt wurde. Wenn Sie BiB in Ihre App einfügen möchten, müssen Sie Ihre Aktivitäten, die BiB unterstützen, registrieren, Ihre Aktivität nach Bedarf in den BiB-Modus versetzen und dafür sorgen, dass UI-Elemente ausgeblendet und die Videowiedergabe fortgesetzt wird, wenn sich die Aktivität im BiB-Modus befindet.

Das BiB-Fenster wird in der obersten Ebene des Bildschirms in einer vom System ausgewählten Ecke angezeigt.

Die Bild-im-Bild-Funktion wird auch auf kompatiblen Android TV OS-Geräten mit Android 14 (API-Level 34) oder höher unterstützt. Es gibt zwar viele Ähnlichkeiten, aber bei der Verwendung von Bild-im-Bild auf dem Fernseher sind einige zusätzliche Aspekte zu berücksichtigen.

So können Nutzer mit dem BiB-Fenster interagieren

Nutzer können das BiB-Fenster an eine andere Stelle ziehen. Ab Android 12 haben Nutzer außerdem folgende Möglichkeiten:

  • Tippen Sie einmal auf das Fenster, um eine Vollbild-Umschaltfläche, eine Schließen-Schaltfläche, eine Einstellungen-Schaltfläche und benutzerdefinierte Aktionen anzuzeigen, die von Ihrer App bereitgestellt werden (z. B. Wiedergabesteuerelemente).

  • Doppeltippen Sie auf das Fenster, um zwischen der aktuellen „Bild im Bild“-Größe und der maximalen oder minimalen „Bild im Bild“-Größe zu wechseln. Wenn Sie beispielsweise auf ein maximiertes Fenster doppeltippen, wird es minimiert. Das Gegenteil ist ebenfalls möglich.

  • Sie können das Fenster ausblenden, indem Sie es an den linken oder rechten Rand ziehen. Wenn Sie das Fenster wiederherstellen möchten, tippen Sie entweder auf den sichtbaren Teil des minimierten Fensters oder ziehen Sie es heraus.

  • Passen Sie die Größe des BiB-Fensters durch Auseinander- und Zusammenziehen an.

Ihre App steuert, wann die aktuelle Aktivität in den PiP-Modus wechselt. Hier einige Beispiele:

  • Eine Aktivität kann in den BiB-Modus wechseln, wenn der Nutzer auf den Home-Button tippt oder nach oben zum Home-Bildschirm wischt. So kann Google Maps weiterhin Wegbeschreibungen anzeigen, während der Nutzer gleichzeitig eine andere Aktivität ausführt.

  • Deine App kann ein Video in den BiB-Modus verschieben, wenn der Nutzer vom Video zurückkehrt, um andere Inhalte zu suchen.

  • Ihre App kann ein Video in den BiB-Modus wechseln, während ein Nutzer das Ende einer Folge ansieht. Auf dem Hauptbildschirm werden Werbe- oder Zusammenfassungsinformationen zur nächsten Folge der Serie angezeigt.

  • Ihre App kann Nutzern die Möglichkeit bieten, zusätzliche Inhalte in die Warteschlange zu stellen, während sie sich ein Video ansehen. Das Video wird im BiB-Modus weiter abgespielt, während auf dem Hauptbildschirm eine Aktivität zur Auswahl von Inhalten angezeigt wird.

BiB-Unterstützung deklarieren

Standardmäßig unterstützt das System PiP für Apps nicht automatisch. Wenn du PiP in deiner App unterstützen möchtest, registriere deine Videoaktivität in deinem Manifest, indem du android:supportsPictureInPicture auf true setzt. Geben Sie außerdem an, dass Ihre Aktivität Änderungen an der Layoutkonfiguration verarbeitet, damit sie nicht neu gestartet wird, wenn während der Übergänge in den PiP-Modus Layoutänderungen auftreten.

<activity android:name="VideoActivity"
    android:supportsPictureInPicture="true"
    android:configChanges=
        "screenSize|smallestScreenSize|screenLayout|orientation"
    ...

Bild-im-Bild-Modus mit Jetpack implementieren

Verwenden Sie die Jetpack-Bibliothek „Bild im Bild“, um die Funktion „Bild im Bild“ zu implementieren. Dadurch wird die Integration vereinfacht und häufige In-App-Probleme werden reduziert. Ein Beispiel für die Verwendung finden Sie in unserer Beispiel-App für die Plattform. Wenn Sie die PiP-Funktion lieber mit den Plattform-APIs implementieren möchten, finden Sie weitere Informationen in der folgenden Dokumentation.

Aktivität in den Bild-im-Bild-Modus wechseln

Ab Android 12 können Sie Ihre Aktivität in den BiB-Modus wechseln, indem Sie das Flag setAutoEnterEnabled auf true setzen. Mit dieser Einstellung wird eine Aktivität bei Bedarf automatisch in den BiB-Modus versetzt, ohne dass enterPictureInPictureMode() in onUserLeaveHint explizit aufgerufen werden muss. Das hat den zusätzlichen Vorteil, dass die Übergänge viel flüssiger sind. Weitere Informationen finden Sie unter Übergänge in den BiB-Modus bei der Bedienung über Gesten optimieren.

Wenn Sie auf Android 11 oder niedriger ausgerichtet sind, 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 in der Benutzeroberfläche der App auf eine entsprechende Schaltfläche klickt:

override fun onActionClicked(action: Action) {
    if (action.id.toInt() == R.id.lb_control_picture_in_picture) {
        activity?.enterPictureInPictureMode()
        return
    }
}

Möglicherweise möchten Sie Logik einfügen, die eine Aktivität in den BiB-Modus schaltet, anstatt in den Hintergrund zu wechseln. Google Maps wechselt beispielsweise in den BiB-Modus, wenn der Nutzer während der Navigation in der App die Startbildschirm- oder die Taste für zuletzt verwendete Apps drückt. Sie können diesen Fall abfangen, indem Sie onUserLeaveHint() überschreiben:

override fun onUserLeaveHint() {
    if (iWantToBeInPipModeNow()) {
        enterPictureInPictureMode()
    }
}

Empfohlen: Nutzern einen reibungslosen Übergang zum BiB-Modus bieten

In Android 12 wurden die animierten Übergänge zwischen Vollbild- und BiB-Fenstern deutlich verbessert. Wir empfehlen dringend, alle anwendbaren Änderungen zu implementieren. Sobald Sie dies getan haben, werden diese Änderungen automatisch auf große Bildschirme wie Faltgeräte und Tablets skaliert, ohne dass weitere Maßnahmen erforderlich sind.

Wenn Ihre App keine entsprechenden Updates enthält, funktionieren PiP-Übergänge weiterhin, die Animationen sind jedoch weniger ausgereift. Wenn Sie beispielsweise vom Vollbild- in den BiB-Modus wechseln, kann es passieren, dass das BiB-Fenster während des Übergangs verschwindet, bevor es nach Abschluss des Übergangs wieder angezeigt wird.

Diese Änderungen umfassen Folgendes:

  • Übergänge in den BiB-Modus bei der Bedienung über Gesten optimiert
  • Einen geeigneten sourceRectHint für den Ein- und Ausstieg aus dem BiB-Modus festlegen
  • Nahtlose Größenanpassung für Inhalte, die keine Videos sind, deaktivieren

Das Android Kotlin PictureInPicture-Beispiel kann als Referenz für die Aktivierung eines reibungslosen Übergangs dienen.

Übergänge in den BiB-Modus bei der Bedienung über Gesten optimieren

Ab Android 12 sorgt das Flag setAutoEnterEnabled für eine viel flüssigere Animation beim Übergang zu Videoinhalten im BiB-Modus mit Gestensteuerung, z. B. beim Hochwischen zum Startbildschirm im Vollbildmodus.

So nehmen Sie die Änderung vor:

  1. Verwenden Sie setAutoEnterEnabled, um PictureInPictureParams.Builder zu erstellen:
setPictureInPictureParams(PictureInPictureParams.Builder()
  .setAspectRatio(aspectRatio)
  .setSourceRectHint(sourceRectHint)
  .setAutoEnterEnabled(true)
  .build())
Note: When `setAutoEnterEnabled` is enabled, you don't need to explicitly
call [`enterPictureInPictureMode`][5] in [`onUserLeaveHint`][6].
  1. Rufen Sie setPictureInPictureParams mit der aktuellen PictureInPictureParams frühzeitig an. Die App wartet nicht auf den onUserLeaveHint-Callback (wie in Android 11).

    Beispielsweise möchten Sie setPictureInPictureParams möglicherweise beim ersten Abspielen und bei jedem nachfolgenden Abspielen aufrufen, wenn sich das Seitenverhältnis ändert.

  2. Rufen Sie setAutoEnterEnabled(false) nur bei Bedarf auf. Wenn die aktuelle Wiedergabe pausiert ist, möchten Sie wahrscheinlich nicht in den BiB-Modus wechseln.

Geeigneten sourceRectHint für den Wechsel in den und aus dem BiB-Modus festlegen

Seit der Einführung von BiB in Android 8.0 gibt setSourceRectHint den Bereich der Aktivität an, der nach dem Übergang in den Bild-im-Bild-Modus sichtbar ist, z. B. die Grenzen der Videoansicht in einem Videoplayer.

In Android 12 verwendet das System sourceRectHint, um sowohl beim Aufrufen als auch beim Beenden des BiB-Modus eine viel flüssigere Animation zu implementieren.

So legen Sie sourceRectHint für den Wechsel in den und aus dem BiB-Modus richtig fest:

  1. Konstruieren Sie PictureInPictureParams mit den richtigen Grenzen als sourceRectHint. Wir empfehlen, dem Videoplayer auch einen Listener für Layoutänderungen anzuhängen:
val mOnLayoutChangeListener =
    OnLayoutChangeListener { v: View?, left: Int,
            top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop:
            Int, oldRight: Int, oldBottom: Int ->
        val sourceRectHint = Rect()
        mYourVideoView.getGlobalVisibleRect(sourceRectHint)
        val builder = PictureInPictureParams.Builder()
            .setSourceRectHint(sourceRectHint)
        setPictureInPictureParams(builder.build())
    }

mYourVideoView.addOnLayoutChangeListener(mOnLayoutChangeListener)
  1. Aktualisieren Sie bei Bedarf die sourceRectHint, bevor das System mit dem Übergang zum Beenden beginnt. Wenn das System den BiB-Modus beendet, wird die Ansichtshierarchie der Aktivität entsprechend der Zielkonfiguration (z. B. Vollbild) angeordnet. Die App kann einen Listener für Layoutänderungen an die Root-Ansicht oder die Zielansicht (z. B. die Videoplayer-Ansicht) anhängen, um das Ereignis zu erkennen und sourceRectHint 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()
        )
    }
}

Nahtlose Größenanpassung für Inhalte, die keine Videos sind, deaktivieren

In Android 12 wurde das Flag setSeamlessResizeEnabled eingeführt, das beim Anpassen der Größe von Nicht-Videoinhalten im BiB-Fenster eine viel flüssigere Überblendungsanimation ermöglicht. Bisher konnte es beim Anpassen der Größe von Nicht-Videoinhalten in einem BiB-Fenster zu störenden visuellen Artefakten kommen.

So aktivieren Sie die nahtlose Größenanpassung für Videoinhalte:

setPictureInPictureParams(PictureInPictureParams.Builder()
    .setSeamlessResizeEnabled(true)
    .build())

Benutzeroberfläche während der BiB-Wiedergabe verarbeiten

Wenn die Aktivität in den Bild-im-Bild-Modus (BiB) wechselt oder diesen verlässt, ruft das System Activity.onPictureInPictureModeChanged() oder Fragment.onPictureInPictureModeChanged() auf.

In Android 15 wurden Änderungen eingeführt, die für einen noch reibungsloseren Übergang beim Wechsel in den BiB-Modus sorgen. Das ist von Vorteil für Apps, bei denen UI-Elemente über der Haupt-UI, die in den BiB-Modus wechselt, eingeblendet werden.

Entwickler verwenden den onPictureInPictureModeChanged()-Callback, um Logik zu definieren, mit der die Sichtbarkeit der überlagerten UI-Elemente umgeschaltet wird. Dieser Callback wird ausgelöst, wenn die Animation für den PiP-Modus abgeschlossen ist. Ab Android 15 enthält die Klasse PictureInPictureUiState einen neuen Status.

Bei diesem neuen UI-Status wird für Apps, die auf Android 15 ausgerichtet sind, der Callback Activity#onPictureInPictureUiStateChanged() mit isTransitioningToPip() aufgerufen, sobald die BiB-Animation beginnt. Viele UI-Elemente sind für die App im BiB-Modus nicht relevant, z. B. Ansichten oder Layouts mit Informationen wie Vorschlägen, dem nächsten Video, Bewertungen und Titeln. Wenn die App in den BiB-Modus wechselt, verwenden Sie den onPictureInPictureUiStateChanged()-Callback, um diese UI-Elemente auszublenden. Wenn die App vom BiB-Fenster in den Vollbildmodus wechselt, verwenden Sie den onPictureInPictureModeChanged()-Callback, um diese Elemente wieder einzublenden, wie in den folgenden Beispielen gezeigt:

override fun onPictureInPictureUiStateChanged(pipState: PictureInPictureUiState) {
    if (pipState.isTransitioningToPip()) {
        // Hide UI elements.
    }
}
override fun onPictureInPictureModeChanged(
    isInPictureInPictureMode: Boolean,
    newConfig: Configuration
) {
    super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
    if (!isInPictureInPictureMode) {
        // Unhide UI elements.
    }
}

Durch das schnelle Ein- und Ausblenden irrelevanter UI-Elemente (für ein BiB-Fenster) wird eine flüssigere und flimmerfreie BiB-Eingangsanimation ermöglicht.

Überschreiben Sie diese Callbacks, um die UI-Elemente der Aktivität neu zu zeichnen. Im BiB-Modus wird Ihre 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. Außerdem sind die Details kleiner UI-Elemente möglicherweise schwer zu erkennen. Video-Wiedergabeaktivitäten mit minimaler Benutzeroberfläche bieten die beste Nutzererfahrung.

Wenn deine App benutzerdefinierte Aktionen für den BiB-Modus bereitstellen muss, lies den Abschnitt Steuerelemente hinzufügen auf dieser Seite. Entfernen Sie andere UI-Elemente, bevor Ihre Aktivität in den BiB-Modus wechselt, und stellen Sie sie wieder her, wenn Ihre Aktivität wieder im Vollbildmodus angezeigt wird.

Steuerelemente hinzufügen

Im BiB-Fenster können Steuerelemente angezeigt werden, wenn der Nutzer das Menü des Fensters öffnet (indem er auf einem Mobilgerät auf das Fenster tippt oder das Menü über die TV-Fernbedienung auswählt).

Wenn eine App eine aktive Mediensitzung hat, werden die Steuerelemente für „Wiedergabe“, „Pause“, „Weiter“ und „Zurück“ angezeigt.

Sie können benutzerdefinierte Aktionen auch explizit angeben, indem Sie PictureInPictureParams mit PictureInPictureParams.Builder.setActions() erstellen, bevor Sie in den BiB-Modus wechseln, und die Parameter beim Wechsel in den BiB-Modus mit enterPictureInPictureMode(android.app.PictureInPictureParams) oder setPictureInPictureParams(android.app.PictureInPictureParams) übergeben. Sei vorsichtig. Wenn Sie versuchen, mehr als getMaxNumPictureInPictureActions() hinzuzufügen, wird nur die maximale Anzahl hinzugefügt.

Videowiedergabe im BiB-Modus fortsetzen

Wenn Ihre Aktivität in den BiB-Modus wechselt, versetzt das System die Aktivität in den pausierten Status und ruft die onPause()-Methode der Aktivität auf. Die Videowiedergabe sollte nicht pausiert werden, sondern fortgesetzt werden, wenn die Aktivität beim Übergang in den BiB-Modus pausiert wird.

Unter Android 7.0 (API-Level 24) und höher sollten Sie die Videowiedergabe pausieren und fortsetzen, wenn das System die onStop()- und onStart()-Methoden Ihrer Aktivität aufruft. So müssen Sie nicht prüfen, ob sich Ihre App im BiB-Modus befindetonPause(), und die Wiedergabe nicht explizit fortsetzen.

Wenn Sie das Flag setAutoEnterEnabled nicht auf true gesetzt haben und die Wiedergabe in Ihrer onPause()-Implementierung pausieren müssen, rufen Sie isInPictureInPictureMode() auf, um den BiB-Modus zu prüfen, und passen Sie die Wiedergabe entsprechend an. Beispiel:

override fun onPause() {
    super.onPause()
    // If called while in PiP mode, don't 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, wird sie vom System fortgesetzt und Ihre onResume()-Methode wird aufgerufen.

Einzelne Wiedergabeaktivität für BiB verwenden

In Ihrer App wählt ein Nutzer möglicherweise ein neues Video aus, während er auf dem Hauptbildschirm nach Inhalten sucht und die Videowiedergabe im BiB-Modus läuft. Spiele das neue Video im Vollbildmodus in der vorhandenen Wiedergabeaktivität ab, anstatt eine neue Aktivität zu starten, die den Nutzer verwirren könnte.

Damit für Videowiedergabeanfragen eine einzelne Aktivität verwendet wird und bei Bedarf in den BiB-Modus gewechselt wird oder der BiB-Modus beendet wird, legen Sie android:launchMode der Aktivität in Ihrem Manifest auf singleTask fest:

<activity android:name="VideoActivity"
    ...
    android:supportsPictureInPicture="true"
    android:launchMode="singleTask"
    ...

Überschreibe in deiner Aktivität onNewIntent() und verarbeite das neue Video. Beende bei Bedarf die Wiedergabe des aktuellen Videos.

Unterstützung von BiB für Kamera-Apps

Damit der BiB-Modus für Kamera-Apps aktiviert werden kann, muss die Kamera im BiB-Modus aktiv bleiben. Schließen Sie die Kamera also nicht, wenn onPause() aufgerufen wird:

override fun onPause() {
    super.onPause()
    // Don't close the camera if the app is entering PiP mode
    if (!isInPictureInPictureMode) {
        closeCamera()
    }
}

Wie bei anderen Anwendungsfällen sollten Sie nicht benötigte UI-Elemente (z. B. Steuerelemente und Overlays) ausblenden und benutzerdefinierte Aktionen zum Steuern der Kamera hinzufügen (z. B. zum Beenden der Aufnahme oder zum Wechseln der Kamera).

sourceRectHint für reibungslose Übergänge berechnen

Für eine reibungslose Einblendanimation ist es wichtig, einen genauen sourceRectHint mit den genauen Bildschirmkoordinaten des Kamerasuchers anzugeben. Sie können die Grenzen aus der Vorschauansicht mit getGlobalVisibleRect() so abrufen:

val previewView = findViewById<View>(R.id.preview_view)
val globalRect = Rect()
// Ensure the view is laid out before calling getGlobalVisibleRect() to get valid screen coordinates.
previewView.getGlobalVisibleRect(globalRect)
val params = PictureInPictureParams.Builder()
    .setSourceRectHint(globalRect)
    .build()
setPictureInPictureParams(params)

Weitere Überlegungen

Auf Geräten mit wenig RAM ist die Bild-im-Bild-Funktion möglicherweise deaktiviert. Bevor Ihre App den BiB-Modus verwendet, sollten Sie mit dem Aufruf von hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE) prüfen, ob er verfügbar ist.

Der Bild-im-Bild-Modus ist für Aktivitäten vorgesehen, bei denen Videos im Vollbildmodus wiedergegeben werden. Wenn Sie Ihre Aktivität in den BiB-Modus wechseln, sollten Sie nur Videoinhalte anzeigen. Verfolge, wann deine Aktivität in den BiB-Modus wechselt, und blende UI-Elemente aus, wie unter UI im BiB-Modus verarbeiten beschrieben.

Wenn sich eine Aktivität im BiB-Modus befindet, erhält sie standardmäßig keinen Eingabefokus. Wenn Sie Eingabeereignisse im BiB-Modus empfangen möchten, verwenden Sie MediaSession.setCallback(). Weitere Informationen zur Verwendung von setCallback() finden Sie unter Now Playing-Card anzeigen.

Wenn sich Ihre App im BiB-Modus befindet, kann die Videowiedergabe im BiB-Fenster zu Audio-Interferenzen mit einer anderen App führen, z. B. einer Musikplayer-App oder einer Sprachsuch-App. Um dies zu vermeiden, fordern Sie den Audiofokus an, wenn Sie die Videowiedergabe starten, und verarbeiten Sie Benachrichtigungen über Änderungen des Audiofokus, wie unter Audiofokus verwalten beschrieben. Wenn Sie im BiB-Modus eine Benachrichtigung über den Verlust des Audiofokus erhalten, pausieren oder beenden Sie die Videowiedergabe.

Wenn Ihre App in den PiP-Modus wechselt, wird nur die oberste Aktivität im Bild-im-Bild-Modus angezeigt. In einigen Situationen, z. B. auf Geräten mit Mehrfenstermodus, kann es vorkommen, dass die zugrunde liegende Aktivität jetzt zusammen mit der BiB-Aktivität angezeigt und wieder sichtbar wird. Sie sollten diesen Fall entsprechend behandeln, einschließlich des Erhalts eines onResume()- oder onPause()-Callbacks für die zugrunde liegende Aktivität. Es ist auch möglich, dass der Nutzer mit der Aktivität interagiert. Wenn beispielsweise eine Videolistenaktivität angezeigt wird und die Aktivität für das wiedergegebene Video im BiB-Modus, kann der Nutzer ein neues Video aus der Liste auswählen. Die BiB-Aktivität sollte dann entsprechend aktualisiert werden.

Zusätzlicher Beispielcode

Eine in Kotlin geschriebene Beispiel-App finden Sie unter Android PictureInPicture Sample (Kotlin).