推薦做法

適用於可折疊和多屏設備的應用程序

通常,應用程序不應依賴靜態標識符或依賴於某些顯示 ID 的邏輯。在大多數情況下,應用程序應該調整大小並在不同的顯示器上運行,並且系統應該控制應用程序的位置。例如,為可折疊設備構建全新的獨特體驗,並在設備折疊時在外部屏幕上啟動一個特殊的應用程序。

在這種情況下,SystemUI(或其他系統組件)應檢測折疊,確定是否適合執行操作,然後啟動目標活動並指定外部顯示 ID 作為啟動目標。應用程序不應檢測此操作或執行任何響應操作,然後在特定顯示器上執行啟動。換句話說,不要假設在一台設備上有效的東西在其他設備上也有效。簡而言之,特定於設備的代碼會增加碎片。

限制對顯示器的訪問

如果設備配置需要限制對一個或多個顯示器的訪問,建議使用Display#FLAG_PRIVATE標誌將此類顯示器指定為private 。這樣做會限制除所有者之外的所有人向顯示器添加內容。除所有者以外的任何人嘗試啟動活動或添加窗口都會導致SecurityException 。如果系統擁有顯示器,則係統可以添加窗口和啟動活動。

此外,放置在顯示器上的實體始終可以訪問該顯示器。如果所有者在顯示器上啟動活動,則該活動可以在該顯示器上啟動其他活動。因此,所有者負責限制訪問並允許受信任的應用程序。

此外,更多的限制被添加到虛擬顯示器,因為任何應用程序都可以創建一個而不讓用戶看到它。如果虛擬顯示器不屬於系統,則只允許具有allowEmbedded的活動,並且調用者應具有ACTIVITY_EMBEDDING權限。

有關更多信息,請參閱:

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

要有條件地控制活動啟動,請使用LaunchParamsController ,它會攔截所有活動啟動並允許系統組件修改用於啟動的參數。這在system_server中可用。

配置顯示窗口設置和系統裝飾

可以在DisplayWindowSettings中為每個顯示器配置系統裝飾。設備實現可以在/data/system/display_settings.xml中提供默認配置。

此值確定係統裝飾(啟動器、壁紙、導航欄和其他裝飾窗口)和 IME 是否出現在顯示器上。有關詳細信息,請參閱DisplayWindowSettings#shouldShowSystemDecorsLocked()DisplayWindowSettings#shouldShowImeLocked()

要識別顯示器,請使用唯一 ID(此默認使用DisplayInfo#uniqueId )或硬件顯示器的物理端口 ID(請參閱DisplayInfo#address )。

例如,以下顯示配置示例在模擬顯示上啟用系統裝飾和 IME:

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

在上面的示例中, uniqueId用於 name 屬性中的顯示標識,對於模擬顯示為overlay:1 。對於內置顯示器,示例值可能是"local:45354385242535243453" 。另一種選擇是使用硬件端口信息並將identifier="1"設置為對應於DisplayWindowSettings#IDENTIFIER_PORT ,然後更新名稱以使用"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>

有關詳細信息,請參閱靜態顯示標識符

有關更多信息,請參閱: