Các phương pháp được đề xuất

Ứng dụng cho thiết bị có thể gập lại và thiết bị có nhiều màn hình

Nói chung, các ứng dụng không nên dựa vào các giá trị nhận dạng tĩnh hoặc logic phụ thuộc vào một số mã nhận dạng màn hình. Trong hầu hết các trường hợp, ứng dụng sẽ đổi kích thước và hoạt động trên nhiều màn hình, đồng thời hệ thống sẽ kiểm soát vị trí đặt ứng dụng. Ví dụ: để tạo trải nghiệm mới và độc đáo cho thiết bị có thể gập lại và chạy một ứng dụng đặc biệt trên màn hình ngoài khi thiết bị ở trạng thái gập.

Trong trường hợp này, SystemUI (hoặc một thành phần hệ thống khác) sẽ phát hiện nếp gấp, xác định xem có nên thực hiện một hành động hay không, sau đó khởi chạy hoạt động mục tiêu và chỉ định một mã nhận dạng màn hình ngoài làm mục tiêu khởi chạy. Ứng dụng không được phát hiện hành động này hoặc thực hiện bất kỳ hành động nào để phản hồi, sau đó thực hiện thao tác khởi chạy trên một màn hình cụ thể. Nói cách khác, đừng cho rằng những gì hoạt động trên một thiết bị sẽ hoạt động trên các thiết bị khác. Nói tóm lại, mã dành riêng cho thiết bị làm tăng sự phân mảnh.

Hạn chế quyền truy cập vào màn hình

Nếu cấu hình thiết bị yêu cầu hạn chế quyền truy cập vào một hoặc nhiều màn hình, thì bạn nên dùng cờ Display#FLAG_PRIVATE để chỉ định các màn hình đó là riêng tư. Thao tác này sẽ hạn chế tất cả người dùng, ngoại trừ chủ sở hữu, thêm nội dung vào bảng quảng cáo. Mọi nỗ lực khởi chạy một hoạt động hoặc thêm một cửa sổ của bất kỳ ai khác ngoài chủ sở hữu đều dẫn đến SecurityException. Nếu hệ thống sở hữu màn hình, thì hệ thống có thể thêm các cửa sổ và khởi chạy các hoạt động.

Ngoài ra, các thực thể được đặt trên một màn hình luôn có thể truy cập vào màn hình đó. Nếu chủ sở hữu chạy một hoạt động trên một màn hình, thì hoạt động đó có thể chạy các hoạt động khác trên màn hình này. Do đó, chủ sở hữu có trách nhiệm hạn chế quyền truy cập và chỉ cho phép các ứng dụng đáng tin cậy.

Ngoài ra, chúng tôi sẽ bổ sung thêm các hạn chế đối với màn hình ảo vì mọi ứng dụng đều có thể tạo một màn hình ảo mà không cần hiển thị cho người dùng. Nếu hệ thống không sở hữu màn hình ảo, thì chỉ những hoạt động có allowEmbedded mới được phép và phương thức gọi phải có quyền ACTIVITY_EMBEDDING.

Để biết thêm thông tin, hãy xem:

  • ActivityStackSupervisor#isCallerAllowedToLaunchOnDisplay()
  • ActivityDisplay#isUidPresent()
  • DisplayManagerService#isUidPresentOnDisplay()

Để kiểm soát có điều kiện việc chạy hoạt động, hãy dùng LaunchParamsController. Lớp này sẽ chặn tất cả các hoạt động chạy và cho phép một thành phần hệ thống sửa đổi các tham số dùng để chạy. Tính năng này có trong system_server.

Định cấu hình chế độ cài đặt cửa sổ hiển thị và thành phần trang trí hệ thống

Bạn có thể định cấu hình thành phần trang trí hệ thống cho mỗi màn hình trong DisplayWindowSettings. Một quy trình triển khai thiết bị có thể cung cấp cấu hình mặc định trong /data/system/display_settings.xml.

Giá trị này xác định xem các thành phần trang trí hệ thống (trình chạy, hình nền, thanh điều hướng và các cửa sổ trang trí khác) và IME có xuất hiện trên màn hình hay không. Để biết thông tin chi tiết, hãy xem DisplayWindowSettings#shouldShowSystemDecorsLocked()DisplayWindowSettings#shouldShowImeLocked().

Để xác định màn hình, hãy dùng mã nhận dạng duy nhất (mã nhận dạng mặc định này dùng DisplayInfo#uniqueId) hoặc mã nhận dạng cổng vật lý cho màn hình phần cứng (xem DisplayInfo#address).

Ví dụ: ví dụ về cấu hình màn hình sau đây cho phép các thành phần trang trí của hệ thống và IME trên màn hình mô phỏng:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<display-settings>
<config identifier="0" />
<display
  name="overlay:1"
  shouldShowSystemDecors="true"
  shouldShowIme="true" />
</display-settings>

Trong ví dụ trên, uniqueId được dùng để nhận dạng màn hình trong thuộc tính tên. Đối với màn hình mô phỏng, thuộc tính này là overlay:1. Đối với màn hình tích hợp, giá trị mẫu có thể là "local:45354385242535243453". Một lựa chọn khác là sử dụng thông tin về cổng phần cứng và đặt identifier="1" tương ứng với DisplayWindowSettings#IDENTIFIER_PORT, sau đó cập nhật tên để sử dụng định dạng "port:<port_id>":

<?xmlversion='1.0' encoding='utf-8' standalone='yes' ?>
<display-settings>
<config identifier="1" />
<display
  name="port:12345"
  shouldShowSystemDecors="true"
  shouldShowIme="true" />
</display-settings>

Để biết thông tin chi tiết, hãy xem phần Giá trị nhận dạng hiển thị tĩnh.

Để biết thêm thông tin, hãy xem: