Android 14 (livello API 34) introduce alcuni miglioramenti alle API Picture in picture (PIP) per consentire il multitasking. Sebbene il supporto della funzionalità PIP sia stato introdotto in Android 8.0 (livello API 26), non era ampiamente supportato su Android TV e non era supportato su Google TV prima di Android 13. Il multitasking per la TV utilizza la modalità PIP per consentire a due app separate di coesistere sullo schermo: una in esecuzione a schermo intero e una in esecuzione in modalità PIP. Esistono requisiti diversi per le app in esecuzione in una di queste modalità.
Il comportamento predefinito è che l'app PiP si sovrappone all'app a schermo intero. Questo è molto simile al comportamento standard della modalità Picture in picture di Android.
Tieni presente che quando integri il multitasking, la tua applicazione deve dichiarare i propri tipi di utilizzo in conformità con le norme sulla qualità delle app TV.
Esegui l'app in modalità PIP
Per i dispositivi TV con Android 14 (livello API 34) o versioni successive, esegui l'app in modalità PIP
chiamando enterPictureInPictureMode()
. I dispositivi TV con versioni precedenti
di Android non supportano la modalità PIP.
Ecco un esempio di come implementare la logica di un pulsante per attivare la modalità 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'azione viene aggiunta solo se il dispositivo dispone della funzionalità di sistema
FEATURE_PICTURE_IN_PICTURE
. Inoltre, quando l'azione viene attivata, le proporzioni della modalità PIP vengono impostate in modo che corrispondano a quelle del video in riproduzione.
Assicurati di aggiungere un titolo e un sottotitolo per fornire all'utente informazioni sull'utilizzo generale di questa funzionalità PIP.
Coesistere con le app in esecuzione in modalità PIP
Quando la tua app viene eseguita come app a schermo intero, potrebbe essere necessario adattarla ad altre app in esecuzione in modalità PIP.
API Keep-clear
In alcuni casi, l'app PIP potrebbe sovrapporsi a componenti UI importanti all'interno dell'app a schermo intero. Per risolvere questo problema, esistono API keep-clear che le app possono utilizzare per identificare i componenti UI critici che non devono essere sovrapposti. Il sistema tenta di rispettare le richieste per evitare di coprire questi componenti riposizionando la finestra PIP.
Per specificare che una visualizzazione non deve essere sovrapposta, utilizza preferKeepClear
nel layout XML come nell'esempio seguente:
<TextView
android:id="@+id/important_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:preferKeepClear="true"
android:text="@string/app_name"/>
Puoi anche farlo a livello di programmazione utilizzando 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); }
A volte non è necessario mantenere pulito l'intero View
, ma solo una sezione. setPreferKeepClearRects()
può essere utilizzato per
specificare le regioni di View
che non devono essere sovrapposte. Le UI che non utilizzano
View
in modo nativo, come Flutter, Jetpack Compose e WebView, potrebbero avere
sottosezioni che richiedono che le regioni rimangano libere. Questa API può essere utilizzata in questi casi.
Tipi di utilizzo
La tua app deve dichiarare un attributo valore metadati di
com.google.android.tv.pip.category
che corrisponde al tipo o ai tipi di utilizzo principali per la modalità Picture in picture. Qualsiasi <activity>
che abbia impostato
android:supportsPictureInPicture="true"
deve dichiarare questo attributo con un
valore pertinente della tabella riportata di seguito.
I tipi di utilizzo che non rientrano in nessuna di queste categorie, in particolare la riproduzione di contenuti multimediali, non sono consentiti in modalità PIP sulla TV.
Valore | Descrizione |
---|---|
"communication " |
Casi d'uso delle comunicazioni, come chiamate vocali o videochiamate. |
"smartHome " |
Integrazioni per la smart home, come campanelli o baby monitor connessi. |
"health " |
Casi d'uso relativi alla salute, come il monitoraggio dell'attività fisica o della salute. |
"ticker " |
Casi d'uso del ticker, ad esempio risultati sportivi in tempo reale o ticker di notizie e azioni. |
Più valori sono separati da una barra verticale (|
). Ad esempio:
<meta-data android:name="com.google.android.tv.pip.category" android:value="smartHome|health" />