W Androidzie 14 (API na poziomie 34) wprowadzono pewne ulepszenia interfejsów API obrazu w obrazie, aby umożliwić wielozadaniowość. Chociaż obsługa PiP została wprowadzona w Androidzie 8.0 (poziom interfejsu API 26), nie była ona powszechnie obsługiwana na Androidzie TV, a w Google TV nie była obsługiwana w ogóle przed Androidem 13. Wielozadaniowość na telewizorze wykorzystuje tryb obrazu w obrazie, aby umożliwić jednoczesne korzystanie z 2 osobnych aplikacji na ekranie: jednej działającej na pełnym ekranie i drugiej działającej w trybie obrazu w obrazie. W przypadku aplikacji działających w tych trybach obowiązują różne wymagania.
Domyślnie aplikacja PiP nakłada się na aplikację pełnoekranową. Jest to bardzo podobne do standardowego działania obrazu w obrazie na Androidzie.
Pamiętaj, że podczas integracji wielozadaniowości aplikacja musi zadeklarować typy użycia zgodnie ze wskazówkami dotyczącymi jakości aplikacji TV.
Uruchamianie aplikacji w trybie obrazu w obrazie
Na urządzeniach TV z Androidem 14 (API na poziomie 34) lub nowszym uruchom aplikację w trybie obrazu w obrazie, wywołując enterPictureInPictureMode(). Telewizory ze starszymi wersjami Androida nie obsługują trybu obrazu w obrazie.
Oto przykład implementacji logiki przycisku do przechodzenia w tryb obrazu w obrazie:
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);
}
}
Działanie jest dodawane tylko wtedy, gdy urządzenie ma funkcję systemową FEATURE_PICTURE_IN_PICTURE. Po uruchomieniu działania format obrazu w trybie obrazu w obrazie jest ustawiany tak, aby odpowiadał formatowi odtwarzanego filmu.
Dodaj tytuł i podtytuł, aby poinformować użytkownika, do czego służy ten proces.
Współistnienie z aplikacjami działającymi w trybie obrazu w obrazie
Gdy aplikacja działa w trybie pełnoekranowym, może być konieczne dostosowanie jej do innych aplikacji działających w trybie obrazu w obrazie.
Interfejsy API Keep-clear
W niektórych przypadkach aplikacja PiP może nakładać się na ważne elementy interfejsu aplikacji na pełnym ekranie. Aby temu zapobiec, aplikacje mogą używać interfejsów API, które pozwalają im identyfikować kluczowe elementy interfejsu, które nie powinny być zasłaniane. System próbuje spełnić te żądania, zmieniając położenie okna obrazu w obrazie, aby nie zasłaniało tych komponentów.
Aby określić, że widok nie powinien być nakładany, użyj preferKeepClear w układzie XML, jak w tym przykładzie:
<TextView
android:id="@+id/important_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:preferKeepClear="true"
android:text="@string/app_name"/>
Możesz to też zrobić automatycznie za pomocą 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);
}
Czasami nie musisz utrzymywać całego View w czystości, ale tylko jego część. Za pomocą właściwości setPreferKeepClearRects() możesz określić regiony View, które nie powinny być nakładane. Interfejsy, które nie używają natywnie View, takie jak Flutter, Jetpack Compose i WebView, mogą mieć podsekcje, które wymagają pozostawienia pustych obszarów. W takich przypadkach można użyć tego interfejsu API.
Rodzaje wykorzystania
Aplikacja musi zadeklarować atrybut wartości metadanych com.google.android.tv.pip.category, który odpowiada głównemu typowi lub głównym typom użycia trybu obrazu w obrazie. Każdy element <activity>, który ma ustawiony atrybut android:supportsPictureInPicture="true", powinien zadeklarować ten atrybut z odpowiednią wartością z poniższej tabeli.
Typy użycia, które nie należą do żadnej z tych kategorii, w szczególności odtwarzanie treści multimedialnych, nie są dozwolone w trybie obrazu w obrazie na telewizorze.
| Wartość | Opis |
|---|---|
„communication” |
Komunikacja, np. rozmowy wideo lub połączenia głosowe. |
„smartHome” |
integracje z inteligentnym domem, takimi jak dzwonki do drzwi czy elektroniczne nianie; |
„health” |
przypadki użycia związane ze zdrowiem, takie jak śledzenie aktywności fizycznej czy monitorowanie stanu zdrowia; |
„ticker” |
przypadki użycia paska informacyjnego, takie jak wyniki sportowe na żywo, wiadomości i notowania giełdowe; |
Wiele wartości jest rozdzielonych pionową kreską (|). Na przykład:
<meta-data android:name="com.google.android.tv.pip.category" android:value="smartHome|health" />