تعدد المهام على التلفزيون

يقدّم الإصدار Android 14 (المستوى 34) بعض التحسينات على واجهة برمجة التطبيقات picture-in-picture (PiP) لإتاحة تعدُّد المهام أثناء وضع "نافذة ضمن النافذة" (PIP) في Android 8.0 (المستوى 26 من واجهة برمجة التطبيقات)، إلا أنه لم يكُن على نطاق واسع على أجهزة Android TV، وغير متاحة على الإطلاق على Google TV الذي يسبق نظام Android. 13- يستخدم تطبيق "تعدد المهام" على التلفزيون وضع "نافذة ضمن النافذة" (PIP) لإتاحة عرضَين تطبيقان منفصلان للعمل على الشاشة: تطبيق يتم تشغيله بالكامل مع تشغيل ثانية في وضع "نافذة ضمن النافذة". تتوفر المتطلبات المختلفة للتطبيقات التي تعمل في أي من هذين الوضعين.

يكون السلوك التلقائي هو أن يكون تطبيق "نافذة ضمن النافذة" يظهر على سطح التطبيق في وضع ملء الشاشة. هذا هو يشبه إلى حد كبير السلوك العادي لميزة نافذة ضمن النافذة على Android.

تجدر الإشارة إلى أنه عند دمج تعدد المهام، يجب أن يعلن تطبيقك عن أنواع الاستخدام في التوافق مع إرشادات الجودة لتطبيقات البث التلفزيوني.

تشغيل تطبيقك في وضع "نافذة ضمن النافذة"

بالنسبة إلى أجهزة التلفزيون التي تعمل بنظام التشغيل Android 14 (المستوى 34 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث، يمكنك تشغيل تطبيقك في وضع "نافذة ضمن النافذة". من خلال الاتصال بالرقم enterPictureInPictureMode(). أجهزة التلفزيون التي يتم تشغيلها في وقت أبكر من السابق لا تتوافق إصدارات Android مع وضع "نافذة ضمن النافذة".

فيما يلي مثال على كيفية تنفيذ منطق الزر للدخول وضع "نافذة ضمن النافذة":

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

لا تتم إضافة الإجراء إلا إذا كان الجهاز يحتوي على ميزة النظام. FEATURE_PICTURE_IN_PICTURE وكذلك، عند تشغيل الإجراء، تمّ ضبط نسبة العرض إلى الارتفاع في وضع "نافذة ضمن النافذة" (PIP) كي تتطابق مع نسبة العرض إلى الارتفاع في الفيديو الحالي. لعبها.

تأكَّد من إضافة عنوان وعنوان فرعي لتزويد المستخدم بمعلومات. حول الغرض من استخدام نافذة ضمن النافذة (PIP) هذه بشكل عام.

التعاون مع التطبيقات التي يتم تشغيلها في وضع "نافذة ضمن النافذة"

عند تشغيل التطبيق كتطبيق ملء الشاشة، قد يحتاج إلى التكيف مع التطبيقات الأخرى تطبيقات تعمل في وضع "نافذة ضمن النافذة".

الاحتفاظ بواجهات برمجة التطبيقات الواضحة

في بعض الحالات، قد تراكب تطبيق "نافذة ضمن النافذة" مكونات مهمة لواجهة المستخدم داخل تطبيق بملء الشاشة. للحدّ من هذه المشاكل، تتوفّر واجهات برمجة تطبيقات واضحة يمكن للتطبيقات استخدامها استخدامها لتحديد مكونات واجهة المستخدم الهامة التي لا ينبغي تركيبها. النظام تلبية الطلبات لتجنب تغطية هذه المكونات من خلال مع تغيير موضع نافذة "نافذة ضمن النافذة".

Keep-واضح

لتحديد عدم تركيب الملف الشخصي، استخدِم 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():

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

في بعض الأحيان، لا تحتاج إلى إبقاء View واضحًا، ولكن جزء فقط منها. يمكن استخدام setPreferKeepClearRects() للأغراض التالية: لتحديد مناطق View التي لا ينبغي أن تظهر فوقها. واجهات المستخدم التي لا تستخدم قد تحتوي أجهزة View في الأصل، مثل Flutter وJetpack Compose وWeb على الأقسام الفرعية التي تحتاج إلى إبقاء المناطق واضحة. ويمكن استخدام واجهة برمجة التطبيقات هذه في هذه الحالات.

أنواع الاستخدام

يجب أن يفصح تطبيقك عن سمة قيمة البيانات الوصفية 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" />