Ab Android 8.0 (API-Level 26) können Aktivitäten im Bild-im-Bild-Modus (BiB) gestartet werden. Der PiP-Modus ist ein spezieller Mehrfenstermodus, der für die Videowiedergabe, Videoanrufe und die Navigation verwendet wird. Nutzer können das vorhandene Aktivitätsfenster an einer Ecke des Bildschirms anpinnen, während sie zwischen Apps wechseln oder sich Inhalte auf dem Hauptbildschirm ansehen.
Für das angepinnte Video-Overlay-Fenster nutzt BiB die in Android 7.0 verfügbaren Mehrfenstermodus-APIs. Wenn Sie Ihrer App BiB hinzufügen möchten, müssen Sie die Aktivitäten registrieren, die BiB unterstützen, die Aktivität nach Bedarf in den BiB-Modus umschalten und dafür sorgen, dass UI-Elemente ausgeblendet werden und die Videowiedergabe fortgesetzt wird, wenn sich die Aktivität im BiB-Modus befindet.
Das PiP-Fenster wird auf der obersten Ebene des Bildschirms in einer vom System ausgewählten Ecke angezeigt.
Der PiP-Modus 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 sind zusätzliche Aspekte zu berücksichtigen.
So können Nutzer mit dem PiP-Fenster interagieren
Nutzer können das BiB-Fenster an eine andere Stelle ziehen. Ab Android 12 können Nutzer außerdem:
Tippe einmal auf das Fenster, um eine Vollbild-Umschaltfläche, eine Schaltfläche zum Schließen, eine Schaltfläche für die Einstellungen und benutzerdefinierte Aktionen deiner App (z. B. Steuerelemente für die Wiedergabe) anzuzeigen.
Doppeltippen Sie auf das Fenster, um zwischen der aktuellen BiB-Größe und der maximalen oder minimalen BiB-Größe zu wechseln. Wenn Sie beispielsweise doppelt auf ein maximiertes Fenster tippen, wird es minimiert. Das Gleiche gilt auch umgekehrt.
Ziehe das Fenster an den linken oder rechten Rand, um es zu minimieren. Wenn Sie das Fenster wiederherstellen möchten, tippen Sie entweder auf den sichtbaren Teil des ausgeblendeten Fensters oder ziehen Sie es heraus.
Du kannst die Größe des BiB-Fensters durch Auseinander- und Zusammenziehen anpassen.
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 den Home-Button tippt oder nach oben wischt, um zum Startbildschirm zu gelangen. 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 sich andere Inhalte anzusehen.
Deine App kann ein Video in den BiB-Modus umschalten, während sich ein Nutzer das Ende einer Folge ansieht. Auf dem Hauptbildschirm werden Werbe- oder Zusammenfassungsinformationen zur nächsten Folge der Serie angezeigt.
Deine 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 Inhaltsauswahl angezeigt wird.
BiB-Unterstützung deklarieren
Standardmäßig wird der Bild-im-Bild-Modus für Apps nicht automatisch unterstützt. 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 sich das Layout während des Übergangs in den Bild-im-Bild-Modus ändert.
<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 PiP-Modus wechseln
Ab Android 12 kannst du deine Aktivität in den BiB-Modus versetzen, indem du das Flag setAutoEnterEnabled auf true setzt. Mit dieser Einstellung wechselt eine Aktivität bei Bedarf automatisch in den PiP-Modus, 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 von der Bedienung über Gesten zum PiP-Modus optimieren.
Wenn Sie Android 11 oder niedriger verwenden, muss eine Aktivität enterPictureInPictureMode() aufrufen, um in den Bild-im-Bild-Modus zu wechseln. Mit dem folgenden Code wird beispielsweise eine Aktivität in den PiP-Modus versetzt, wenn der Nutzer auf einen bestimmten Button 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
}
}
Sie können Logik einbinden, die eine Aktivität in den PiP-Modus schaltet, anstatt sie in den Hintergrund zu verschieben. Google Maps wechselt beispielsweise in den PiP-Modus, wenn der Nutzer die Startbildschirmtaste oder die Taste für die zuletzt verwendeten Apps drückt, während die App navigiert. Sie können diesen Fall abfangen, indem Sie onUserLeaveHint() überschreiben:
override fun onUserLeaveHint() {
if (iWantToBeInPipModeNow()) {
enterPictureInPictureMode()
}
}
Empfohlen: Nutzern einen optimierten Übergang zum PiP-Modus bieten
In Android 12 wurden die animierten Übergänge zwischen Vollbild- und PiP-Fenstern optisch deutlich verbessert. Wir empfehlen dringend, alle anwendbaren Änderungen zu implementieren. Sobald Sie dies getan haben, werden diese Änderungen automatisch auf große Bildschirme wie faltbare Geräte und Tablets skaliert, ohne dass weitere Arbeit erforderlich ist.
Wenn deine App keine entsprechenden Updates enthält, funktionieren PiP-Übergänge zwar weiterhin, die Animationen sind jedoch weniger ausgefeilt. Beispielsweise kann der Übergang vom Vollbild- zum BiB-Modus dazu führen, dass das BiB-Fenster während des Übergangs verschwindet und erst nach Abschluss des Übergangs wieder angezeigt wird.
Diese Änderungen umfassen Folgendes:
- Übergänge von der Bedienung über Gesten zum PiP-Modus wurden optimiert.
- Festlegen eines geeigneten
sourceRectHintfür den Ein- und Ausstieg aus dem PiP-Modus - Nahtlose Größenanpassung für Inhalte, die keine Videos sind, deaktivieren
Im Android Kotlin PictureInPicture-Beispiel finden Sie eine Referenz für die Aktivierung eines optimierten Übergangs.
Übergänge von der Bedienung über Gesten zum PiP-Modus flüssiger gestalten
Ab Android 12 sorgt das Flag setAutoEnterEnabled für eine viel flüssigere Animation beim Übergang zu Videoinhalten im Bild-im-Bild-Modus über die Bedienung über Gesten, z. B. wenn Sie im Vollbildmodus nach oben wischen, um zum Startbildschirm zu gelangen.
Führen Sie die folgenden Schritte aus, um diese Änderung vorzunehmen:
- Verwenden Sie
setAutoEnterEnabled, umPictureInPictureParams.Builderzu 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].
Rufen Sie
setPictureInPictureParamsfrühzeitig mit der aktuellenPictureInPictureParamsauf. Die App wartet nicht auf den CallbackonUserLeaveHint(wie es unter Android 11 der Fall gewesen wäre).Beispielsweise können Sie
setPictureInPictureParamsbei der allerersten Wiedergabe und bei jeder nachfolgenden Wiedergabe aufrufen, wenn sich das Seitenverhältnis ändert.Rufen Sie
setAutoEnterEnabled(false)auf, aber nur, wenn es nötig ist. Beispielsweise möchten Sie den PiP-Modus wahrscheinlich nicht aktivieren, wenn die aktuelle Wiedergabe pausiert ist.
Lege einen geeigneten sourceRectHint für das Aufrufen und Verlassen des PiP-Modus fest.
Seit der Einführung von BiB in Android 8.0 gibt setSourceRectHint den Bereich der Aktivität an, der nach dem Übergang zu BiB sichtbar ist, z. B. die Grenzen der Videoansicht in einem Videoplayer.
Unter Android 12 verwendet das System sourceRectHint, um eine viel flüssigere Animation sowohl beim Aufrufen als auch beim Verlassen des BiB-Modus zu implementieren.
So legen Sie sourceRectHint für das Starten und Beenden des PiP-Modus richtig fest:
- Erstellen Sie
PictureInPictureParamsmit den richtigen Grenzen alssourceRectHint. Wir empfehlen, auch einen Layoutänderungs-Listener an den Videoplayer 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)
- Aktualisieren Sie bei Bedarf die
sourceRectHint, bevor das System den Exit-Übergang startet. Wenn das System den PiP-Modus beendet, wird die Ansichtshierarchie der Aktivität auf die Zielkonfiguration (z. B. Vollbild) festgelegt. Die App kann einen Listener für Layoutänderungen an die Stammansicht oder die Zielansicht (z. B. die Videoplayer-Ansicht) anhängen, um das Ereignis zu erkennen und diesourceRectHintvor 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 Nicht-Videoinhalte deaktivieren
In Android 12 wird das Flag setSeamlessResizeEnabled hinzugefügt, das eine viel flüssigere Überblendungsanimation beim Ändern der Größe von Nicht-Videoinhalten im PiP-Fenster ermöglicht. Bisher konnte das Ändern der Größe von Nicht-Videoinhalten in einem BiB-Fenster zu störenden visuellen Artefakten führen.
So aktivieren Sie die nahtlose Größenanpassung für Videoinhalte:
setPictureInPictureParams(PictureInPictureParams.Builder()
.setSeamlessResizeEnabled(true)
.build())
Benutzeroberfläche während der Bild-im-Bild-Wiedergabe verarbeiten
Wenn die Aktivität in den Bild-im-Bild-Modus wechselt oder diesen verlässt, ruft das System Activity.onPictureInPictureModeChanged() oder Fragment.onPictureInPictureModeChanged() auf.
Android 15 führt Änderungen ein, die einen noch reibungsloseren Übergang beim Wechsel in den PiP-Modus ermöglichen. Das ist nützlich für Apps, bei denen UI-Elemente über der Haupt-UI eingeblendet werden, die in den BiB-Modus wechselt.
Entwickler verwenden den Callback onPictureInPictureModeChanged(), um die Logik zu definieren, mit der die Sichtbarkeit der überlagerten UI-Elemente ein- und ausgeschaltet wird. Dieser Callback wird ausgelöst, wenn die Animation zum Starten oder Beenden des 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 PiP-Animation beginnt. Es gibt viele UI-Elemente, die für die App im PiP-Modus nicht relevant sind, z. B. Ansichten oder Layouts mit Informationen wie Vorschlägen, dem nächsten Video, Bewertungen und Titeln. Wenn die App in den PiP-Modus wechselt, verwende den Callback onPictureInPictureUiStateChanged(), um diese UI-Elemente auszublenden. Wenn die App vom PiP-Fenster in den Vollbildmodus wechselt, verwende den Callback onPictureInPictureModeChanged(), 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 PiP-Fenster) wird eine flüssigere und flimmerfreie Animation beim Aufrufen des PiP-Modus ermöglicht.
Überschreiben Sie diese Callbacks, um die UI-Elemente der Aktivität neu zu zeichnen. Beachten Sie, dass Ihre Aktivität im PiP-Modus in einem kleinen Fenster angezeigt wird. Nutzer können nicht mit den UI-Elementen Ihrer App interagieren, wenn sich die App im PiP-Modus befindet. Außerdem sind die Details kleiner UI-Elemente möglicherweise schwer zu erkennen. Videowiedergabeaktivitäten mit minimaler Benutzeroberfläche bieten die beste Nutzererfahrung.
Wenn deine App benutzerdefinierte Aktionen für den PiP-Modus bereitstellen muss, findest du weitere Informationen unter Steuerelemente hinzufügen auf dieser Seite. Entferne andere UI-Elemente, bevor deine Aktivität in den PiP-Modus wechselt, und stelle sie wieder her, wenn deine 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 (durch Tippen auf das Fenster auf einem Mobilgerät oder durch Auswählen des Menüs mit der TV-Fernbedienung).
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 vor dem Wechsel in den BiB-Modus PictureInPictureParams mit PictureInPictureParams.Builder.setActions() erstellen 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.
Fortsetzung der Videowiedergabe im BiB-Modus
Wenn die Aktivität in den PiP-Modus wechselt, wird sie vom System pausiert und die Methode onPause() der Aktivität wird aufgerufen. Die Videowiedergabe sollte nicht pausiert werden, sondern fortgesetzt werden, wenn die Aktivität beim Wechsel 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 onStop() und onStart() Ihrer Aktivität aufruft. So müssen Sie nicht in onPause() prüfen, ob sich Ihre App 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, prüfe, ob der PiP-Modus aktiv ist, indem du isInPictureInPictureMode() aufrufst, und verarbeite die Wiedergabe entsprechend. 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 die Aktivität vom PiP-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 PiP verwenden
In deiner App kann ein Nutzer ein neues Video auswählen, wenn er auf dem Hauptbildschirm nach Inhalten sucht, während eine Videowiedergabeaktivität im BiB-Modus läuft. Spiele das neue Video in der vorhandenen Wiedergabeaktivität im Vollbildmodus ab, anstatt eine neue Aktivität zu starten, die den Nutzer verwirren könnte.
Damit eine einzelne Aktivität für Videowiedergabeanfragen verwendet und nach Bedarf in den BiB-Modus oder aus dem BiB-Modus gewechselt wird, legen Sie in Ihrem Manifest für android:launchMode der Aktivität den Wert 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 vorhandenen Videos.
PiP für Kamera-Apps unterstützen
Wenn du PiP für Kamera-Apps aktivieren möchtest, musst du dafür sorgen, dass die Kamera im PiP-Modus aktiv bleibt. Schließe 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 unbedingt erforderliche UI-Elemente (z. B. Steuerelemente und Overlays) ausblenden und benutzerdefinierte Aktionen zur Steuerung der Kamera hinzufügen (z. B. Aufnahme beenden oder Kamera umdrehen).
sourceRectHint für flüssige Übergänge berechnen
Die Angabe eines genauen sourceRectHint mit den exakten Bildschirmkoordinaten des Kamerasuchers ist für eine reibungslose Einstiegsanimation unerlässlich. 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 PiP möglicherweise deaktiviert. Bevor deine App den PiP-Modus verwendet, solltest du prüfen, ob er verfügbar ist. Rufe dazu hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE) auf.
Der PiP-Modus ist für Aktivitäten gedacht, bei denen Videos im Vollbildmodus abgespielt werden. Wenn du deine Aktivität in den BiB-Modus wechselst, solltest du nur Videoinhalte anzeigen. Erfasse, wann deine Aktivität in den PiP-Modus wechselt, und blende UI-Elemente aus, wie unter UI-Elemente im PiP-Modus verwalten beschrieben.
Wenn sich eine Aktivität im PiP-Modus befindet, erhält sie standardmäßig keinen Eingabefokus. Wenn du im PiP-Modus Eingabeereignisse empfangen möchtest, verwende MediaSession.setCallback().
Weitere Informationen zur Verwendung von setCallback() findest du unter Now Playing-Card anzeigen.
Wenn sich Ihre App im BiB-Modus befindet, kann die Videowiedergabe im BiB-Fenster zu Audiostörungen mit einer anderen App führen, z. B. einer Musikplayer-App oder einer App für die Sprachsuche. Um dies zu vermeiden, fordern Sie den Audiofokus an, wenn Sie mit der Wiedergabe des Videos beginnen, und verarbeiten Sie Benachrichtigungen über Änderungen des Audiofokus, wie unter Audiofokus verwalten beschrieben. Wenn du im PiP-Modus eine Benachrichtigung erhältst, dass der Audiofokus verloren gegangen ist, pausiere oder beende die Videowiedergabe.
Wenn deine App in den PiP-Modus wechselt, wird nur die oberste Aktivität in den PiP-Modus versetzt. In einigen Situationen, z. B. auf Geräten mit Mehrfenstermodus, ist es möglich, dass die zugrunde liegende Activity jetzt neben der BiB-Activity angezeigt und wieder sichtbar wird. Sie sollten diesen Fall entsprechend behandeln, einschließlich der zugrunde liegenden Aktivität, die einen onResume()- oder onPause()-Callback erhält.
Es ist auch möglich, dass der Nutzer mit der Aktivität interagiert.
Wenn du beispielsweise eine Aktivität mit einer Videoliste und die Aktivität mit dem abgespielten Video im PiP-Modus hast, kann der Nutzer ein neues Video aus der Liste auswählen und die PiP-Aktivität sollte entsprechend aktualisiert werden.
Zusätzlicher Beispielcode
Eine Beispiel-App in Kotlin finden Sie unter Android PictureInPicture Sample (Kotlin).