ทําหลายอย่างพร้อมกันบนทีวี

Android 14 (API ระดับ 34) มีการปรับปรุงบางอย่างใน API การแสดงภาพซ้อนภาพ (PiP) เพื่อให้ทำงานหลายอย่างพร้อมกันได้ แม้ว่าการรองรับ PiP จะเปิดตัวใน Android 8.0 (API ระดับ 26) แต่ก็ไม่ได้รับการรองรับอย่างแพร่หลายใน Android TV และไม่รองรับเลยใน Google TV ก่อน Android 13 การทำงานหลายอย่างพร้อมกันสำหรับทีวีใช้โหมด PIP เพื่อให้แอป 2 แอปที่แยกกันอยู่ร่วมกันบนหน้าจอได้ โดยแอปหนึ่งทำงานแบบเต็มหน้าจอ และแอปที่ 2 ทำงานในโหมด PIP แอปที่ทำงานในโหมดใดโหมดหนึ่งเหล่านี้จะมีข้อกำหนดที่แตกต่างกัน

ลักษณะการทำงานเริ่มต้นคือแอป PiP จะวางซ้อนแอปแบบเต็มหน้าจอ ซึ่งคล้ายกับลักษณะการทำงานของการแสดงภาพซ้อนภาพใน Android แบบมาตรฐาน

โปรดทราบว่าเมื่อผสานรวมการทำงานหลายอย่างพร้อมกัน แอปพลิเคชันของคุณต้องประกาศประเภทการใช้งานตามหลักเกณฑ์ด้านคุณภาพของแอป TV

เรียกใช้แอปในโหมด PIP

สำหรับอุปกรณ์ทีวีที่ใช้ Android 14 (ระดับ API 34) ขึ้นไป ให้เรียกใช้แอปในโหมด PiP โดยเรียกใช้ enterPictureInPictureMode() อุปกรณ์ทีวีที่ใช้ Android เวอร์ชันก่อนหน้าจะไม่รองรับโหมด PiP

ต่อไปนี้คือตัวอย่างวิธีใช้ตรรกะของปุ่มเพื่อเข้าสู่โหมด PIP

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 นี้โดยทั่วไป

ทำงานร่วมกับแอปที่ทำงานในโหมด PIP

เมื่อแอปทำงานเป็นแอปแบบเต็มหน้าจอ แอปอาจต้องปรับให้เข้ากับแอปอื่นๆ ที่ทำงานในโหมด PIP

Keep-clear API

ในบางกรณี แอป PiP อาจวางซ้อนคอมโพเนนต์ UI ที่สำคัญภายในแอปแบบเต็มหน้าจอ เพื่อลดปัญหานี้ จึงมี Keep-Clear API ที่แอปสามารถใช้เพื่อระบุคอมโพเนนต์ UI ที่สำคัญซึ่งไม่ควรวางซ้อน ระบบจะพยายามทำตามคำขอเพื่อหลีกเลี่ยงการบดบังคอมโพเนนต์เหล่านี้โดยการเปลี่ยนตำแหน่งหน้าต่าง PiP

การจัดตำแหน่งหน้าต่าง PiP เพื่อหลีกเลี่ยงการบดบังคอมโพเนนต์ UI ที่สำคัญ
รูปที่ 1 การจัดตำแหน่งหน้าต่าง PiP เพื่อหลีกเลี่ยงการบดบังคอมโพเนนต์ UI ที่สำคัญ

หากต้องการระบุว่าไม่ควรวางซ้อนมุมมอง ให้ใช้ 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 ที่ไม่ควรวางซ้อนทับได้ UI ที่ไม่ได้ใช้ 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" />