Android 14 (API düzeyi 34), çoklu görev yapmaya olanak tanımak için pencere içinde pencere (PiP) API'lerinde bazı iyileştirmeler sunar. PiP desteği Android 8.0'da (API düzeyi 26) kullanıma sunulmuş olsa da Android TV'de yaygın olarak desteklenmiyordu ve Android 13'ten önce Google TV'de hiç desteklenmiyordu. TV için çoklu görev, PiP modunu kullanarak iki ayrı uygulamanın ekranda aynı anda bulunmasına olanak tanır: Biri tam ekranda, diğeri ise PiP modunda çalışır. Bu modlardan birinde çalışan uygulamalar için farklı şartlar vardır.
Varsayılan davranış, PiP uygulamasının tam ekran uygulamanın üzerine yerleştirilmesidir. Bu, standart Android pencere içinde pencere davranışıyla hemen hemen aynıdır.
Çoklu görev özelliğini entegre ederken uygulamanızın, TV uygulama kalitesi yönergelerine uygun olarak kullanım türlerini beyan etmesi gerektiğini unutmayın.
Uygulamanızı PiP modunda çalıştırma
Android 14 (API düzeyi 34) veya sonraki sürümlerin yüklü olduğu TV cihazlarında enterPictureInPictureMode() yöntemini çağırarak uygulamanızı PiP modunda çalıştırın. Android'in önceki sürümlerini çalıştıran TV cihazları PiP modunu desteklemez.
Aşağıda, PiP moduna girmek için bir düğmenin mantığının nasıl uygulanacağına dair bir örnek 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 için başlık ve alt başlık eklediğinizden emin olun.
PiP modunda çalışan uygulamalarla birlikte çalışma
Uygulamanız tam ekran olarak çalışırken PiP modunda çalışan diğer uygulamalara uyum sağlaması gerekebilir.
Keep-clear API'leri
Bazı durumlarda PiP uygulaması, tam ekran uygulamasındaki önemli kullanıcı arayüzü bileşenlerinin üzerine yerleştirilebilir. Bu sorunu azaltmak için uygulamaların, üzerine yerleştirilmemesi gereken kritik kullanıcı arayüzü bileşenlerini tanımlamak amacıyla kullanabileceği Keep-Clear API'leri vardır. Sistem, PiP penceresini yeniden konumlandırarak bu bileşenlerin kapatılmasını önleme isteklerini yerine getirmeye çalışır.
Bir görünümün yer paylaşımı olarak kullanılmaması gerektiğini belirtmek için XML düzeninizde aşağıdaki örnekte gösterildiği 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);
}
Bazı durumlarda View'nin tamamını değil, yalnızca bir bölümünü boş bırakmanız gerekebilir. setPreferKeepClearRects(), View öğesinin üzerine yerleştirilmemesi gereken bölgelerini belirtmek için kullanılabilir. Flutter, Jetpack Compose ve WebView gibi View'leri yerel olarak kullanmayan kullanıcı arayüzlerinde, boş tutulması gereken bölgelerin bulunduğu alt bölümler olabilir. Bu API, bu gibi 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 com.google.android.tv.pip.category değerinde bir meta veri değeri özelliği beyan etmelidir. android:supportsPictureInPicture="true" ayarlanmış tüm <activity>, bu özelliği aşağıdaki tablodan alakalı bir değerle beyan etmelidir.
Bu kategorilerden hiçbirine 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" |
Görüntülü görüşme veya sesli arama 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 haber ve borsa kayan yazıları gibi kayan yazı kullanım alanları. |
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" />