系統裝飾支援

以下為這些多媒體特定區域的更新:

系統裝飾

Android 10 開始支援設定次要版本 顯示特定系統裝飾,例如桌布、導覽列 和啟動器根據預設,主要螢幕會顯示所有系統裝飾。 次要螢幕則會顯示這些選用。支援輸入法編輯器 (IME) 可以與其他系統裝飾分開設定。

使用「DisplayWindowSettings#setShouldShowSystemDecorsLocked()」 新增對特定螢幕的系統裝飾支援 做為 /data/system/display_settings.xml 中的預設值。例如 請參閱「顯示視窗設定」。

實作

DisplayWindowSettings#setShouldShowSystemDecorsLocked()也會顯示在 WindowManager#setShouldShowSystemDecors() 進行測試。這個方法的觸發 意圖啟用系統裝飾,不會新增 或者移除先前存在的檔案。大多數 系統裝飾的支援變更只會在 重新啟動裝置。

檢查 WindowManager 程式碼集內系統裝飾的支援情形 通常經過 DisplayContent#supportsSystemDecorations() 檢查外部服務,例如系統 UI 檢查導覽列 應顯示) 使用 WindowManager#shouldShowSystemDecors()。 如要瞭解這項設定所控制的項目,請查看 這些方法。

系統 UI 裝飾視窗

Android 10 新增系統裝飾視窗支援功能 「只有」導覽列,因為導覽列非常重要 瀏覽活動和應用程式。根據預設,導覽列會顯示 「返回」和「居家生活」適用。只有在目標螢幕支援的情況下,系統才會納入這個欄位 系統裝飾 (請參閱 DisplayWindowSettings)。

狀態列 是比較複雜的系統視窗 也包含通知欄、快速設定和螢幕鎖定畫面。在 Android 中 10,次要顯示器不支援狀態列。 因此,通知、設定和完整鍵盤鎖僅適用於 主螢幕。

次要執行個體不支援 Overview/Recents 系統視窗 螢幕。在 Android 10 中,Android 開放原始碼計畫只會在 預設顯示,並且包含所有螢幕的活動。從以下位置啟動時 近期事件:在次要顯示器上的活動 預設顯示畫面此方法有一些已知問題,例如 應用程式在其他螢幕上顯示時會立即更新。

實作

如要實作其他系統 UI 功能,裝置製造商應使用 單一系統 UI 元件,監聽新增/移除螢幕及 提供適當內容

支援多螢幕 (MD) 的系統 UI 元件應處理 下列情況:

  • 啟動時多個螢幕初始化
  • 已在執行階段新增螢幕
  • 已在執行階段移除螢幕

系統 UI 在 WindowManager 之前偵測到新增螢幕時,即會建立 競爭狀況如要避免這種情況,只要在以下項目中實作自訂回呼即可: 新增螢幕時 (而非訂閱) 時,將 WindowManager 新增至系統 UI DisplayManager.DisplayListener 事件。如需參考實作 請參閱 CommandQueue.Callbacks#onDisplayReady,瞭解導覽列支援 和 WallpaperManagerInternal#onDisplayReady 則用於桌布。

此外,Android 10 還提供以下更新:

  • NavigationBarController 類別可控管所有功能 只提供導覽列專屬的功能
  • 如要查看自訂導覽列,請參閱 CarStatusBar
  • TYPE_NAVIGATION_BAR》不再僅限於單一 而且可以按螢幕使用。
  • IWindowManager#hasNavigationBar() 已更新以納入 displayId 參數僅適用於系統 UI。

發射器

在 Android 10 中,每個螢幕設定為 系統裝飾具有專屬主堆疊,用於執行具有類型的啟動器活動 預設為 WindowConfiguration#ACTIVITY_TYPE_HOME。每個螢幕 使用獨立的啟動器活動執行個體。

圖 1. 多螢幕啟動器範例 platform/development/samples/MultiDisplay

大多數現有的啟動器都不支援多個執行個體,且未最佳化 適合大螢幕使用此外,使用者體驗也經常會有所不同 次要/外部螢幕為次要執行個體提供專屬活動 Android 10 的螢幕,在意圖中引入 SECONDARY_HOME 類別 篩選器。這項活動的執行個體會用於支援系統的所有螢幕 裝飾,每個展示品一張。

<activity>
    ...
    <intent-filter>
        <category android:name="android.intent.category.SECONDARY_HOME" />
        ...
    </intent-filter>
</activity>

活動的啟動模式必須不會防止多個 而且應配合不同的螢幕大小進行調整啟動模式 但不能是 singleInstancesingleTask

實作

在 Android 10 中,RootActivityContainer#startHomeOnDisplay() 會根據螢幕,自動選取所需的元件和意圖 也就是啟動主畫面的指令RootActivityContainer#resolveSecondaryHomeActivity() 包含查詢啟動器活動元件的邏輯,其會依據目前的 所選啟動器,並視需要使用系統預設值 (請參閱 ActivityTaskManagerService#getSecondaryHomeIntent())。

安全性限制

除了適用於次要顯示器上活動的限制外, ,避免惡意應用程式 系統裝飾 以及從介面讀取使用者的機密資訊,則只有在啟動器出現時 顯示在系統擁有的虛擬螢幕上啟動器無法在 非系統的虛擬螢幕

桌布

在 Android 10 以上版本中,支援桌布 在次要螢幕上播放:

圖 2. 內部 (上方) 和外部的動態桌布 顯示器 (如下圖)

開發人員可以藉由提供 android:supportsMultipleDisplays="true"WallpaperInfo XML 定義。許多桌布開發人員 應該使用 WallpaperService.Engine#getDisplayContext()

這個架構會建立一個 WallpaperService.Engine 執行個體 因此每個引擎都有專屬的介面和顯示內容。 開發人員必須確定每個引擎都能獨立繪製 不同的影格速率,依循 VSYNC。

選擇個別畫面的桌布

Android 10 無法直接支援平台選取桌布 分別對應個別螢幕為了達成這個目標,固定顯示 ID 為 。 Display#getDisplayId() 為動態值,因此無法保證一定能 實體螢幕在重新啟動後都會擁有相同的 ID。

不過,Android 10 新增了 DisplayInfo.mAddress。 包含實體螢幕的固定 ID,適用於 日後導入的功能可惜的是,目前實作邏輯的期限已過 Android 10 應用程式建議解決方案:

  1. 使用 WallpaperManager API 設定桌布。
  2. WallpaperManagerContext 取得 物件,而每個 Context 物件都有對應的相關資訊 螢幕 (Context#getDisplay()/getDisplayId())。因此 從 WallpaperManager 執行個體取得 displayId 不必新增新方法
  3. 在架構方面,使用displayId Context 物件並對應至靜態 ID (例如 實體螢幕)。使用靜態 ID 保留所選桌布。

這個解決方法將現有的實作方式用於桌布挑選器。如果是 使用了正確的內容 呼叫設定桌布,系統會自動識別螢幕。

如果需要為目前螢幕以外的螢幕設定桌布 顯示,然後建立新的 Context 物件用於目標顯示畫面 (Context#createDisplayContext),並取得 畫面顯示的 WallpaperManager 例項。

安全性限制

系統不會在虛擬螢幕上顯示非專屬桌布。 這是因為惡意應用程式可能在建立虛擬機器時 支援系統裝飾的螢幕,以及讀取使用者相關動作 顯示的資訊 (例如個人相片)。

實作

在 Android 10 中,IWallpaperConnection#attachEngine()IWallpaperService#attach() 介面接受 建立個別螢幕連線的 displayId 參數。 WallpaperManagerService.DisplayConnector 會封裝每個螢幕 桌布引擎和連線在 WindowManager 中,桌布控制器是 建構時為每個 DisplayContent 物件建立,而不是建立 針對所有螢幕採用單一 WallpaperController

部分公開的 WallpaperManager 方法實作 (例如 WallpaperManager#getDesiredMinimumWidth()) 已更新為運算資源 並提供相應螢幕的資訊 WallpaperInfo#supportsMultipleDisplays() 和對應的 新增資源屬性,方便應用程式開發人員回報 現在可以在多台螢幕上顯示桌布了。

如果預設螢幕顯示的桌布服務不支援 多個螢幕,然後將次要裝置的預設桌布 螢幕。

圖 3. 次要螢幕的桌布備用邏輯