TV'de çoklu görev

Android 14 (API düzeyi 34), pencere içinde pencere (PiP) API'lerinde çoklu görev gerçekleştirmeye imkan tanıyan bazı iyileştirmeler sunar. PiP desteği Android 8.0 (API düzeyi 26) sürümünde kullanıma sunulmuş olsa da Android TV'de yaygın şekilde desteklenmiyordu ve Android 13'ten önce Google TV'de hiç desteklenmiyordu. TV için çoklu görev özelliği, biri tam ekranda, ikincisi ise PiP modunda olmak üzere iki ayrı uygulamanın ekranda bir arada sunulmasına izin vermek için PiP modunu kullanır. Bu modlardan birinde çalışan uygulamalar için farklı gereksinimler vardır.

Varsayılan davranış, PiP uygulamasının tam ekran uygulamada yer paylaşımlı olmasıdır. Bu, standart Android pencere içinde pencere davranışıyla hemen hemen aynıdır.

Çoklu görev entegrasyonu sırasında uygulamanızın kullanım türlerini TV uygulaması kalite yönergelerine uygun olarak beyan etmesi gerektiğini unutmayın.

Uygulamanızı PiP modunda çalıştırma

Android 14 (API düzeyi 34) veya sonraki sürümleri çalıştıran TV cihazlarda enterPictureInPictureMode() numaralı telefonu arayarak uygulamanızı PiP modunda çalıştırın. Android'in önceki sürümlerini çalıştıran TV cihazları PiP modunu desteklemez.

PiP moduna girmek için bir düğmenin mantığının nasıl uygulanacağına dair bir örneği aşağıda bulabilirsiniz:

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);
    }
}

İşlem yalnızca cihazda FEATURE_PICTURE_IN_PICTURE sistem özelliği varsa eklenir. Ayrıca, işlem tetiklendiğinde PiP modunun en boy oranı, oynatılan videonun en boy oranıyla eşleşecek şekilde ayarlanır.

Bu PIP'nin genellikle ne için kullanıldığıyla ilgili kullanıcıya bilgi vermek için bir başlık ve alt başlık eklediğinizden emin olun.

PiP modunda çalışan uygulamalarla birlikte kullanılabilir

Uygulamanız tam ekran uygulama olarak çalışırken PiP modunda çalışan diğer uygulamalara uyum sağlaması gerekebilir.

Net API'ler

Bazı durumlarda PiP uygulaması, önemli kullanıcı arayüzü bileşenlerini tam ekran uygulamasına yerleştirebilir. Bu durumu azaltmak amacıyla, uygulamaların yer paylaşımlı olmaması gereken önemli kullanıcı arayüzü bileşenlerini tanımlamak için kullanabileceği net API'ler mevcuttur. Sistem, PiP penceresini yeniden konumlandırarak bu bileşenleri kapsamamak için istekleri yerine getirmeye çalışır.

Açık Tutun

Bir görünümün yer paylaşımlı olmaması gerektiğini belirtmek için XML düzeninizde aşağıdaki örnekte olduğu gibi preferKeepClear kullanın:

<TextView
    android:id="@+id/important_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:preferKeepClear="true"
    android:text="@string/app_name"/>

Bu işlemi setPreferKeepClear() kullanarak programatik olarak da yapabilirsiniz:

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);
}

Bir View öğesinin tamamını netleştirmeniz gerekmeyen ancak yalnızca bir bölümünü net tutmanız gereken zamanlar olabilir. setPreferKeepClearRects(), View bölgesinin yer paylaşımlı olmaması gereken bölgelerini belirtmek için kullanılabilir. View öğelerini yerel olarak kullanmayan Flutter, Jetpack Compose ve WebView gibi kullanıcı arayüzlerinin, bölgelerin net tutulması gereken alt bölümleri olabilir. Bu API bu tür durumlarda kullanılabilir.

Kullanım türleri

Uygulamanız, pencere içinde pencere modunun birincil kullanım türüne veya türlerine karşılık gelen bir com.google.android.tv.pip.category meta veri değeri özelliği beyan etmelidir. android:supportsPictureInPicture="true" değerini ayarlayan tüm <activity>, bu özelliği aşağıdaki tablodan alakalı bir değerle tanımlamalıdır.

Bu kategorilere girmeyen kullanım türlerine, özellikle de medya içeriğinin oynatılmasına TV'de pencere içinde pencere modunda izin verilmez.

Değer Açıklama
"communication" İletişimle ilgili kullanım alanları (ör. görüntülü veya sesli aramalar).
"smartHome" Bağlı kapı zilleri veya bebek monitörü gibi akıllı ev entegrasyonları.
"health" Fitness takibi veya sağlık takibi gibi sağlıkla ilgili kullanım alanları.
"ticker" Hisse senedi kullanım alanları (ör. canlı spor karşılaşmalarının skorları veya haberler ve hisse senedi sembolleri).

Birden fazla değer dikey çubukla (|) ayrılır. Örneğin:

<meta-data android:name="com.google.android.tv.pip.category" android:value="smartHome|health" />