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

Android 14 (API ระดับ 34) มีการปรับปรุงบางอย่างใน API ภาพในภาพ (PiP) เพื่อให้สามารถทำงานหลายอย่างพร้อมกันได้ แม้ว่าการรองรับ PIP จะเปิดตัวใน Android 8.0 (API ระดับ 26) แต่ Android TV ก็ไม่ได้รองรับอย่างกว้างขวาง และไม่รองรับใน Google TV รุ่นก่อน Android 13 เลย การทำงานหลายอย่างพร้อมกันสำหรับทีวีใช้โหมด PIP เพื่อให้แอป 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

API แบบไม่ต้องเสียเวลา

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

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" Use Case ของทิกเกอร์ เช่น คะแนนการแข่งขันกีฬาแบบสดหรือข่าวและทิกเกอร์หุ้น

ค่าหลายค่าจะคั่นด้วยแท่งแนวตั้ง (|) ตัวอย่างเช่น

<meta-data android:name="com.google.android.tv.pip.category" android:value="smartHome|health" />