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ı geliştirmeler sunar. PiP desteği Android 8.0'da (API düzeyi 26) kullanıma sunulmasına rağmen Android TV'de yaygın olarak desteklenmedi ve Android 13'ten önceki Google TV'de hiç desteklenmedi. 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ı şartlar 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 özelliğini entegre ederken uygulamanızın kullanım türlerini TV uygulaması kalite yönergelerine uygun şekilde belirtmesi 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 örnek aşağıda verilmiştir:

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.

Kullanıcıya bu PIP'nin genel olarak ne için kullanıldığı hakkında bilgi vermek üzere bir başlık ve altyazı eklediğinizden emin olun.

PiP modunda çalışan uygulamalarla birlikte çalışabilir.

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şenlerin kapatılmasını önlemek 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"/>

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

Bazen View öğesinin tamamını değil, yalnızca bir bölümünü temiz tutmanız gerekebilir. setPreferKeepClearRects(), View bölgesinin yer paylaşımlı olmaması gereken bölgelerini belirtmek için kullanılabilir. Flutter, Jetpack Compose ve WebView gibi View'leri doğal olarak kullanmayan kullanıcı arayüzlerinde, bölgelerin boş tutulması gereken alt bölümler olabilir. Bu API, bu tür durumlar için kullanılabilir.

Kullanım türleri

Uygulamanız, pencere içinde pencere modunun birincil türüne veya türlerine karşılık gelen com.google.android.tv.pip.category meta veri değeri özelliği bildirmelidir. 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 kategorilerin hiçbirine girmeyen kullanım türlerine (özellikle medya içeriği oynatma) TV'de pencere içinde pencere modunda izin verilmez.

Değer Açıklama
"communication" Görüntülü veya sesli aramalar gibi iletişim amaçlı kullanım alanları.
"smartHome" Bağlı kapı zilleri veya bebek monitörleri gibi akıllı ev entegrasyonları
"health" Fitness takibi veya sağlık izleme gibi sağlıkla ilgili kullanım alanları.
"ticker" Canlı spor skorları veya haberler ve hisse senedi akışları gibi akış kullanımı alanları.

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

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