Android 14 (niveau d'API 34) introduit certaines améliorations apportées aux API Picture-in-picture (PIP) pour permettre le multitâche. Bien que la prise en charge du PIP ait été introduite dans Android 8.0 (niveau d'API 26), elle n'était pas largement prise en charge sur Android TV et n'était pas du tout prise en charge sur Google TV avant Android 13. Le multitâche pour la TV utilise le mode PIP pour permettre à deux applications distinctes de coexister à l'écran: l'une s'exécute en plein écran et l'autre en mode PIP. Les exigences diffèrent selon que les applications s'exécutent dans l'un ou l'autre de ces modes.
Le comportement par défaut est que l'application PIP se superpose à l'application en plein écran. Ce comportement est très semblable au comportement Picture-in-picture standard d'Android.
Notez que lors de l'intégration du mode multitâche, votre application doit déclarer ses types d'utilisation conformément aux consignes relatives à la qualité des applications TV.
Exécuter votre application en mode PIP
Pour les téléviseurs équipés d'Android 14 (niveau d'API 34) ou version ultérieure, exécutez votre application en mode PIP en appelant enterPictureInPictureMode()
. Les téléviseurs équipés de versions antérieures d'Android ne sont pas compatibles avec le mode PIP.
Voici un exemple d'implémentation de la logique d'un bouton pour passer en mode PIP:
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); } }
L'action n'est ajoutée que si l'appareil dispose de la fonctionnalité système FEATURE_PICTURE_IN_PICTURE
. En outre, lorsque l'action est déclenchée, le format du mode PIP est défini pour correspondre au format de la vidéo en cours de lecture.
Veillez à ajouter un titre et un sous-titre pour donner à l'utilisateur des informations sur l'utilisation générale de cette fenêtre PIP.
Coexister avec des applications s'exécutant en mode PIP
Lorsque votre application s'exécute en plein écran, elle devra peut-être s'adapter à d'autres applications exécutées en mode PIP.
API de clarté
Dans certains cas, l'application PIP peut superposer des composants d'interface utilisateur importants dans l'application en plein écran. Pour limiter ce problème, les applications peuvent utiliser des API claires qui permettent d'identifier les composants d'interface utilisateur critiques qui ne doivent pas être superposés. Le système tente de respecter les requêtes pour éviter de couvrir ces composants en repositionnant la fenêtre PIP.
Pour spécifier qu'une vue ne doit pas être superposée, utilisez preferKeepClear
dans votre mise en page XML, comme dans l'exemple suivant:
<TextView
android:id="@+id/important_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:preferKeepClear="true"
android:text="@string/app_name"/>
Vous pouvez également effectuer cette opération par programmation à l'aide de setPreferKeepClear()
:
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); }
Il peut arriver que vous n'ayez pas besoin de garder une View
entière claire, mais seulement une partie de celui-ci. Le setPreferKeepClearRects()
permet de spécifier les régions du View
qui ne doivent pas être superposées. Les interfaces utilisateur qui n'utilisent pas de View
de manière native, telles que Flutter, Jetpack Compose et WebView, peuvent comporter des sous-sections pour lesquelles les régions doivent être clairement maintenues. Cette API peut être utilisée dans ce cas.
Types d'utilisation
Votre application doit déclarer un attribut de valeur de métadonnées com.google.android.tv.pip.category
qui correspond au type principal ou aux types d'utilisation du mode Picture-in-picture. Tout <activity>
qui a défini android:supportsPictureInPicture="true"
doit déclarer cet attribut avec la valeur appropriée indiquée dans le tableau ci-dessous.
Les types d'utilisation qui n'appartiennent à aucune de ces catégories, en particulier toute lecture de contenu multimédia, ne sont pas autorisés en mode Picture-in-picture sur les téléviseurs.
Valeur | Description |
---|---|
"communication " |
Cas d'utilisation pour les communications, comme les appels vidéo ou vocaux. |
"smartHome " |
Des intégrations pour la maison connectée, comme les sonnettes connectées ou les babyphones |
"health " |
Cas d'utilisation pour la santé, comme le suivi de l'activité physique ou de la santé. |
"ticker " |
Cas d'utilisation d'indices, tels que les résultats sportifs en direct, les actualités et les valeurs boursières. |
Les valeurs multiples sont séparées par une barre verticale (|
). Par exemple :
<meta-data android:name="com.google.android.tv.pip.category" android:value="smartHome|health" />