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

В 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

Если ваше приложение работает в полноэкранном режиме, возможно, ему потребуется адаптироваться к другим приложениям, работающим в режиме PiP.

Сохраняйте ясность API

В некоторых случаях приложение PiP может накладывать важные компоненты пользовательского интерфейса на полноэкранное приложение. Чтобы смягчить это, существуют API-интерфейсы Keep Clear, которые приложения могут использовать для определения критических компонентов пользовательского интерфейса, которые не следует перекрывать. Система пытается удовлетворить запросы, чтобы не закрывать эти компоненты, изменяя положение окна PiP.

Держитесь подальше

Чтобы указать, что представление не должно накладываться, используйте в макете XML preferKeepClear , как показано в следующем примере:

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