Android 14 (API cấp 34) giới thiệu một số tính năng nâng cao cho Hình trong hình (PiP) để hỗ trợ người dùng thao tác đa nhiệm. Trong khi chế độ Hình trong hình được giới thiệu từ Android 8.0 (API cấp 26), nhưng tính năng này chưa được áp dụng rộng rãi được hỗ trợ trên Android TV và hoàn toàn không được hỗ trợ trên Google TV trước Android 13. Chế độ đa nhiệm đối với TV sử dụng chế độ PiP để cho phép riêng biệt các ứng dụng để cùng tồn tại trên màn hình: một ứng dụng chạy hoàn toàn với một giây chạy ở chế độ PiP. Có các yêu cầu khác nhau đối với ứng dụng chạy ở một trong hai chế độ này.
Hành vi mặc định là ứng dụng PiP phủ lên ứng dụng toàn màn hình. Đây là giống như hành vi hình trong hình tiêu chuẩn của Android.
Lưu ý rằng khi tích hợp đa nhiệm, ứng dụng của bạn phải khai báo các loại cách sử dụng trong tuân thủ các nguyên tắc về chất lượng đối với ứng dụng truyền hình.
Chạy ứng dụng ở chế độ PiP (Hình trong hình)
Đối với các thiết bị TV chạy Android 14 (API cấp 34) trở lên, hãy chạy ứng dụng của bạn ở chế độ Hình trong hình
bằng cách gọi enterPictureInPictureMode()
. Các thiết bị TV chạy sớm hơn
phiên bản Android không hỗ trợ chế độ PiP.
Dưới đây là ví dụ về cách triển khai logic của một nút để nhập Chế độ 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); } }
Hành động chỉ được thêm vào nếu thiết bị có tính năng hệ thống
FEATURE_PICTURE_IN_PICTURE
. Ngoài ra, khi hành động được kích hoạt,
Tỷ lệ khung hình của chế độ PiP được thiết lập để khớp với tỷ lệ khung hình của video đang được
đã phát.
Hãy nhớ thêm tiêu đề và phụ đề để cung cấp thông tin người dùng về mục đích sử dụng của video PIP này.
Cùng tồn tại với các ứng dụng chạy ở chế độ Hình trong hình
Khi đang chạy dưới dạng ứng dụng toàn màn hình, ứng dụng đó có thể cần phải thích ứng với các ứng dụng chạy ở chế độ PiP.
API Keep-clear
Trong một số trường hợp, ứng dụng PiP có thể phủ các thành phần giao diện người dùng quan trọng trong ứng dụng toàn màn hình. Để giảm thiểu điều này, ứng dụng có thể dùng các API rõ ràng dùng để xác định các thành phần giao diện người dùng quan trọng không nên phủ lên. Hệ thống cố gắng thực hiện yêu cầu để tránh che giấu các thành phần này bằng cách đặt lại vị trí cửa sổ PiP.
Để chỉ định rằng một thành phần hiển thị không được phủ lên, hãy sử dụng preferKeepClear
trong
Bố cục XML như trong ví dụ sau:
<TextView
android:id="@+id/important_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:preferKeepClear="true"
android:text="@string/app_name"/>
Bạn cũng có thể thực hiện việc này theo phương thức lập trình bằng 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); }
Có thể đôi khi bạn không cần giữ rõ toàn bộ View
, nhưng
chỉ một phần của địa điểm đó. Bạn có thể sử dụng setPreferKeepClearRects()
để
chỉ định các vùng của View
không được phủ lên. Giao diện người dùng không sử dụng
Các View
vốn có, chẳng hạn như Flutter, Jetpack Compose và WebView, có thể
các phần phụ cần thông báo rõ ràng về các khu vực. Bạn có thể sử dụng API này cho những trường hợp đó.
Kiểu sử dụng
Ứng dụng của bạn phải khai báo thuộc tính giá trị siêu dữ liệu là
com.google.android.tv.pip.category
tương ứng với loại chính hoặc
cách sử dụng cho chế độ hình trong hình. Mọi <activity>
đã đặt
android:supportsPictureInPicture="true"
phải khai báo thuộc tính này bằng một
giá trị phù hợp trong bảng dưới đây.
Những cách sử dụng không thuộc bất kỳ danh mục nào trong số này, cụ thể là không được phép phát nội dung nghe nhìn ở chế độ hình trong hình trên TV.
Giá trị | Mô tả |
---|---|
"communication " |
Các trường hợp sử dụng tính năng giao tiếp, chẳng hạn như cuộc gọi video hoặc cuộc gọi thoại. |
"smartHome " |
Các thiết bị tích hợp nhà thông minh, chẳng hạn như chuông cửa đã kết nối hoặc thiết bị giám sát em bé. |
"health " |
Các trường hợp sử dụng liên quan đến sức khoẻ, chẳng hạn như theo dõi hoạt động thể dục hoặc theo dõi sức khoẻ. |
"ticker " |
Các trường hợp sử dụng tin tức, chẳng hạn như tỷ số thể thao trực tiếp hoặc tin tức và mã cổ phiếu. |
Nhiều giá trị được phân tách bằng dấu gạch đứng (|
). Ví dụ:
<meta-data android:name="com.google.android.tv.pip.category" android:value="smartHome|health" />