Android 14 (уровень API 34) вводит некоторые улучшения в API «картинка в картинке» (PiP), чтобы обеспечить многозадачность. Хотя поддержка PiP была представлена в Android 8.0 (уровень API 26), она не получила широкой поддержки на Android TV и вообще не поддерживалась на Google TV до Android 13. Многозадачность для ТВ использует режим PiP, чтобы два отдельных приложения могли сосуществовать на экране: одно работало в полноэкранном режиме, а второе — в режиме PiP. Для приложений, работающих в любом из этих режимов, существуют разные требования.
Поведение по умолчанию заключается в том, что приложение PiP накладывается на полноэкранное приложение. Это во многом похоже на стандартное поведение Android «картинка в картинке» .
Обратите внимание, что при интеграции многозадачности ваше приложение должно декларировать типы использования в соответствии с рекомендациями по качеству телевизионных приложений .
Запустите приложение в режиме PiP
Для ТВ-устройств под управлением 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 устанавливается в соответствии с соотношением сторон воспроизводимого видео.
Обязательно добавьте заголовок и подзаголовок, чтобы предоставить пользователю информацию о том, для чего обычно используется эта картинка в картинке.
Сосуществование с приложениями, работающими в режиме PiP
Если ваше приложение работает в полноэкранном режиме, ему может потребоваться адаптация для других приложений, работающих в режиме PiP.
API-интерфейсы Keep-Clear
В некоторых случаях приложение PiP может перекрывать важные компоненты пользовательского интерфейса в полноэкранном приложении. Чтобы смягчить это, существуют API-интерфейсы keep-clear, которые приложения могут использовать для определения критических компонентов пользовательского интерфейса, которые не должны перекрываться. Система пытается удовлетворить запросы, чтобы избежать перекрытия этих компонентов, изменяя положение окна PiP.
Чтобы указать, что представление не должно накладываться, используйте 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" />