Multitasking sulla TV

Android 14 (livello API 34) introduce alcuni miglioramenti alle API picture-in-picture (PiP) per consentire il multitasking. Mentre PIP il supporto è stato introdotto in Android 8.0 (livello API 26), non era supportata su Android TV e non supportata su Google TV prima di Android 13: Il multitasking per la TV utilizza la modalità PiP per consentire la coesistenza sullo schermo di due app distinte: una in esecuzione a schermo intero e una in modalità PiP. Esistono requisiti diversi per le app in esecuzione in una di queste modalità.

Per impostazione predefinita, l'app PIP si sovrappone all'app a schermo intero. Questo è in modo molto simile al comportamento standard di Picture in picture di Android.

Tieni presente che, quando integri il multitasking, la tua applicazione deve dichiarare i suoi 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, della modalità PIP sia impostata per corrispondere alle proporzioni del video riprodotto.

Assicurati di aggiungere un titolo e un sottotitolo per fornire all'utente informazioni sullo scopo solitamente di questa PIP.

Coesiste con le app in esecuzione in modalità PIP

Quando la tua app viene eseguita a schermo intero, potrebbe dover essere adattata per altre app in esecuzione in modalità PiP.

Mantieni la cancellazione delle API

In alcuni casi, l'app PiP potrebbe sovrapporre componenti importanti dell'interfaccia utente all'interno dell'app in modalità a schermo intero. Per ovviare a questo problema, esistono API keep-clear che le app possono utilizzare per identificare i componenti critici dell'interfaccia utente che non devono essere sovrapposti. Il sistema tenta di soddisfare le richieste per evitare di coprire questi componenti con e riposizionare la finestra PIP.

Keep-Clear

Per specificare che una visualizzazione non deve essere sovrapposta, utilizza preferKeepClear nei 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 in modo programmatico 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);
}

Può capitare che non sia necessario tenere in chiaro un elemento View, ma solo una sezione. setPreferKeepClearRects() può essere utilizzato per specificare le regioni del View che non devono essere sovrapposte. Le UI che non utilizzano View in modo nativo, come Flutter, Jetpack Compose e WebView, possono avere sottosezioni che richiedono regioni non occupate. In questi casi è possibile utilizzare l'API.

Tipi di utilizzo

La tua app deve dichiarare un attributo valore dei metadati di com.google.android.tv.pip.category che corrisponde al tipo principale o tipi di utilizzo della modalità Picture in picture. Qualsiasi <activity> che ha impostato android:supportsPictureInPicture="true" deve dichiarare questo attributo con un valore pertinente riportato nella tabella 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 di comunicazione, come videochiamate o chiamate vocali.
"smartHome" Integrazioni per la smart home, ad esempio campanelli connessi o baby monitor.
"health" Casi d'uso per la salute, come il monitoraggio dell'attività fisica o il monitoraggio della salute.
"ticker" Casi d'uso dei ticker, come i risultati sportivi in diretta o le notizie e i ticker azionari.

Una barra verticale (|) separa più valori. Ad esempio:

<meta-data android:name="com.google.android.tv.pip.category" android:value="smartHome|health" />