Многозадачность на телевизоре

В 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» для определения критически важных компонентов пользовательского интерфейса, которые не должны перекрываться. Система пытается удовлетворить запросы, чтобы избежать перекрытия этих компонентов, изменяя положение окна «картинка в картинке».

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" />