В Android 14 (API уровня 34) реализованы некоторые улучшения API режима «картинка в картинке» (PiP), обеспечивающие многозадачность. Хотя поддержка режима «картинка в картинке» появилась в Android 8.0 (API уровня 26), она не получила широкой поддержки на Android TV и не поддерживалась вовсе на Google TV до Android 13. Многозадачность на ТВ использует режим «картинка в картинке», позволяющий двум приложениям одновременно работать на экране: одному в полноэкранном режиме, а второму — в режиме «картинка в картинке». Требования к приложениям, работающим в этих режимах, различаются.
По умолчанию приложение «Картинка в картинке» накладывается поверх полноэкранного приложения. Это во многом похоже на стандартное поведение Android «картинка в картинке» .
Обратите внимание, что при интеграции многозадачности ваше приложение должно объявлять типы своего использования в соответствии с рекомендациями по качеству телевизионных приложений .
Запустите приложение в режиме «картинка в картинке»
Для телевизоров под управлением Android 14 (уровень API 34) или выше запустите приложение в режиме PiP, вызвав enterPictureInPictureMode()
. Телевизоры под управлением более ранних версий Android не поддерживают режим PiP.
Вот пример реализации логики кнопки для входа в режим PiP:
Котлин
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 } }
Ява
@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); } }
Действие добавляется только при наличии на устройстве системной функции FEATURE_PICTURE_IN_PICTURE
. Кроме того, при запуске действия соотношение сторон режима «картинка в картинке» устанавливается в соответствии с соотношением сторон воспроизводимого видео.
Обязательно добавьте заголовок и подзаголовок, чтобы предоставить пользователю информацию о том, для чего обычно используется эта картинка в картинке.
Сосуществование с приложениями, работающими в режиме «картинка в картинке»
Если ваше приложение работает в полноэкранном режиме, возможно, его придется адаптировать для других приложений, работающих в режиме PiP.
API-интерфейсы Keep-Clear
В некоторых случаях приложение «картинка в картинке» может перекрывать важные компоненты пользовательского интерфейса в полноэкранном приложении. Чтобы избежать этого, приложения могут использовать API-интерфейсы с функцией «keep-clear» для определения критически важных компонентов пользовательского интерфейса, которые не должны перекрываться. Система пытается удовлетворить запросы, чтобы избежать перекрытия этих компонентов, изменяя положение окна «картинка в картинке».
Чтобы указать, что представление не должно накладываться, используйте preferKeepClear
в вашем XML-макете, как в следующем примере:
<TextView
android:id="@+id/important_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:preferKeepClear="true"
android:text="@string/app_name"/>
Вы также можете сделать это программно, используя setPreferKeepClear()
:
Котлин
private lateinit var binding: MyLayoutBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = MyLayoutBinding.inflate(layoutInflater) setContentView(binding.root) binding.importantText.isPreferKeepClear = true }
Ява
private MyLayoutBinding binding; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = MyLayoutBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); binding.importantText.setPreferKeepClear(true); }
Иногда может потребоваться сохранять чистым не всё View
, а только его часть. Метод setPreferKeepClearRects()
можно использовать для указания областей View
, которые не должны перекрываться. В пользовательских интерфейсах, не использующих View
изначально, таких как Flutter, Jetpack Compose и WebView, могут быть подразделы, которые необходимо сохранять чистыми. Для таких случаев можно использовать этот API.
Типы использования
Ваше приложение должно объявить атрибут метаданных com.google.android.tv.pip.category
, соответствующий основному типу или типам использования режима «картинка в картинке». Любой элемент <activity>
, для которого задано android:supportsPictureInPicture="true"
должен объявить этот атрибут с соответствующим значением из таблицы ниже.
Типы использования, которые не попадают ни в одну из этих категорий, в частности любое воспроизведение медиаконтента, не допускаются в режиме «картинка в картинке» на телевизоре.
Ценить | Описание |
---|---|
" communication " | Варианты использования средств связи, такие как видео- или голосовые звонки. |
" smartHome " | Интеграция с интеллектуальными системами дома, например, подключенными дверными звонками или радионянями. |
" health " | Примеры использования в здравоохранении, такие как отслеживание физической формы или мониторинг состояния здоровья. |
" ticker " | Примеры использования тикеров: прямые трансляции спортивных состязаний, новости и биржевые тикеры. |
Несколько значений разделяются вертикальной чертой ( |
). Например:
<meta-data android:name="com.google.android.tv.pip.category" android:value="smartHome|health" />