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

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

عملکرد پیش‌فرض این است که برنامه «تصویردرتصویر» روی برنامه تمام‌صفحه رونهاد می‌شود. این عملکرد بسیار شبیه عملکرد استاندارد تصویردرتصویر Android است.

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

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

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

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

میاناهای برنامه‌سازی کاربردی «فاصله ایمن»

در برخی موارد، برنامه «تصویردرتصویر» ممکن است عناصر مهم رابط کاربری را در برنامه تمام‌صفحه رونهاد کند. برای کاهش این مشکل، APIهایی وجود دارد که برنامه‌ها می‌توانند از آن‌ها برای شناسایی عناصر مهم رابط کاربری که نباید رونهاد شوند استفاده کنند. سیستم تلاش می‌کند با تغییر موقعیت پنجره «تصویردرتصویر»، درخواست‌های اجتناب از پوشاندن این عناصر را برآورده کند.

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

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

انواع کاربری

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