چندوظیفگی در تلویزیون

Android 14 (سطح میانای برنامه‌سازی کاربردی ۳۴) بهبودهایی را در میاناهای برنامه‌سازی کاربردی تصویردرتصویر (PiP) برای امکان چندوظیفگی معرفی می‌کند. درحالی‌که پشتیبانی از PiP در Android 8.0 (سطح میانای برنامه‌سازی کاربردی ۲۶) معرفی شد، به‌طور گسترده در Android TV پشتیبانی نمی‌شد و در Google TV قبل‌از Android 13 اصلاً پشتیبانی نمی‌شد. چندوظیفگی برای تلویزیون از حالت PiP استفاده می‌کند تا دو برنامه جداگانه بتوانند به‌طور هم‌زمان در صفحه وجود داشته باشند: یکی در حالت تمام‌صفحه اجرا می‌شود و دیگری در حالت PiP. برای برنامه‌هایی که در هریک از این حالت‌ها اجرا می‌شوند، الزامات متفاوتی وجود دارد.

رفتار پیش‌فرض این است که برنامه PiP روی برنامه تمام‌صفحه قرار می‌گیرد. این رفتار بسیار شبیه به رفتار استاندارد تصویردرتصویر Android است.

توجه داشته باشید که هنگام ادغام چندوظیفگی، برنامه شما باید انواع استفاده خود را مطابق با دستورالعمل‌های کیفیت برنامه تلویزیون اعلام کند.

اجرای برنامه در حالت «تصویر در تصویر»

برای دستگاه‌های تلویزیون با Android نسخه ۱۴ (سطح میانای برنامه‌سازی کاربردی ۳۴) یا بالاتر، برنامه‌تان را با فراخوانی enterPictureInPictureMode() در حالت «تصویر در تصویر» اجرا کنید. دستگاه‌های تلویزیونی که نسخه‌های قدیمی‌تر Android را اجرا می‌کنند از حالت 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 اجرا می‌شوند

وقتی برنامه‌تان به‌عنوان برنامه تمام‌صفحه اجرا می‌شود، ممکن است لازم باشد با برنامه‌های دیگری که در حالت «تصویردرتصویر» اجرا می‌شوند سازگار شود.

میاناهای برنامه‌سازی کاربردی Keep-clear

در برخی موارد، برنامه PiP ممکن است روی مؤلفه‌های مهم میانای کاربر در برنامه تمام‌صفحه قرار بگیرد. برای کاهش این مشکل، میاناهای برنامه‌سازی کاربردی keep-clear وجود دارد که برنامه‌ها می‌توانند از آن‌ها برای شناسایی مؤلفه‌های حیاتی میانای کاربر که نباید روی آن‌ها قرار بگیرد استفاده کنند. سیستم تلاش می‌کند با تغییر موقعیت پنجره «تصویر در تصویر»، درخواست‌ها را برای جلوگیری از پوشاندن این مؤلفه‌ها رعایت کند.

جای‌گذاری پنجره «تصویردرتصویر» برای جلوگیری از پوشاندن مؤلفه‌های مهم میانای کاربر
شکل ۱. قرار دادن پنجره «تصویردرتصویر» به‌گونه‌ای که مؤلفه‌های مهم میانای کاربری را نپوشاند.

برای مشخص کردن اینکه یک نما نباید هم‌پوشانی شود، از 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() انجام دهید:

کاتلین

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 که نباید هم‌پوشانی شوند استفاده کرد. واسط‌های کاربری که به‌طور بومی از Views استفاده نمی‌کنند، مثل Flutter،‏ Jetpack Compose، و WebView، ممکن است بخش‌های فرعی داشته باشند که لازم باشد نواحی آن‌ها خالی نگه داشته شود. از این میانای برنامه‌سازی کاربردی می‌توان برای این موارد استفاده کرد.

انواع استفاده

برنامه شما باید ویژگی مقدار فراداده 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" />