多媒體廣告支援

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

調整活動和螢幕的大小

如要指出應用程式可能不支援多視窗模式或大小調整功能, 活動會使用 resizeableActivity=false 屬性。一般 調整活動大小時應用程式會發生的問題包括:

  • 活動可能會有與應用程式不同設定 非視覺元件常見錯誤是讀取應用程式中的顯示指標 相關資訊傳回的值不會調整為以下區域的可見區域指標: 是用於顯示活動
  • 活動可能無法處理大小調整和當機情形、顯示扭曲的 UI、 或是因重新啟動而不儲存執行個體狀態而導致狀態遺失。
  • 應用程式可能會嘗試使用絕對的輸入座標,而非 相對的,這可能會打斷輸入的 多視窗模式

在 Android 7 (和更高版本) 中,您可將應用程式設定為 resizeableActivity=false:一律在全螢幕模式中執行。於 在此例中,平台可避免無法調整大小的活動進入分割畫面。 。如果使用者嘗試從啟動器叫用無法調整大小的活動 而處於分割畫面模式時,平台會結束分割畫面模式 在全螢幕模式下啟動無法調整大小的活動。

已在false 除非相容性條件一致,否則不得在多視窗模式下啟動資訊清單。 模式:

  • 相同的設定會套用至程序,其中包含所有活動 和非活動元件
  • 套用的設定符合 CDD 應用程式相容性的規定 螢幕。

在 Android 10 中,平台仍會禁止 無法調整大小的活動進入分割畫面模式 如果活動已宣告固定方向或長寬比,則會暫時縮放 比例。如果沒有,活動會調整大小來填滿整個螢幕,如同 Android 所示 9 以下。

預設的導入方式會套用下列政策:

當活動宣告與多視窗模式不相容時 使用 android:resizeableActivity 屬性時 活動符合下述任一條件, 必須更改螢幕設定,活動和程序就會與 原始設定,同時為使用者提供重新啟動服務的預設用途 讓應用程式程序使用更新後的螢幕設定。

  • 透過套用 android:screenOrientation
  • 應用程式的預設顯示比例上限或下限 (依指定 API 級別區分) 或者明確宣告顯示比例

此圖顯示了具有宣告顯示比例且無法調整大小的活動。 摺疊裝置時,視窗會縮小,以配合區域 保持長寬比。此外, 每當系統顯示 變更活動

展開裝置時,裝置的設定、大小和顯示比例 活動不會受到影響,但會顯示重新啟動活動的選項。

未設定 resizeableActivity 時 (或設為 true),應用程式可完整支援調整大小。

實作

呼叫固定方向或顯示比例的無法調整大小活動 程式碼的大小相容性模式 (SCM)。該條件的定義如下: ActivityRecord#shouldUseSizeCompatMode()。發生 SCM 活動時 螢幕相關設定 (例如大小或密度) 固定不變 都會在要求的覆寫設定中,因此活動就不再相依 目前的顯示設定上

如果 SCM 活動無法填滿整個畫面,則會以頂端對齊並 水平置中。活動邊界是由 AppWindowToken#calculateCompatBoundsTransformation()

SCM 活動使用的螢幕設定與 容器 (例如:調整顯示畫面的大小,或活動移至另一個 顯示)、ActivityRecord#inSizeCompatMode() 為 true, SizeCompatModeActivityController (在系統 UI 中) 收到 這個回呼,顯示程序重新啟動按鈕。

顯示大小和顯示比例

Android 10 支援新的顯示比例 包括長篇與細長型螢幕的高比例,以及 1:1 比例。應用程式可以定義 ApplicationInfo#maxAspectRatio 以及畫面的 ApplicationInfo#minAspectRatio 處理程式碼的方式

Android 10 中的應用程式比例

圖 1. Android 支援的應用程式比例範例 10 分

裝置實作可具有具有大小和規格的次要螢幕 解析度小於 Android 9 所需的解析度 (最低為 2.5) 英寸寬度或高度,smallestScreenWidth 的最低 320 DP; 不過,只有選擇支援這些小型螢幕的活動才能放置在 好在那裡。

應用程式只需宣告支援的大小下限,該值即可小於或等於 或等於目標顯示大小使用 android:minHeight 和 在「群組」中的 android:minWidth 活動版面配置屬性 使用 AndroidManifest。

顯示政策

Android 10 分離及移動特定螢幕 預設 WindowManagerPolicy 實作中的政策 PhoneWindowManager 到個別顯示類別,例如:

  • 顯示狀態和旋轉
  • 部分按鍵和動作事件追蹤
  • 系統 UI 和裝飾視窗

在 Android 9 (及以下版本) 中,系統會處理 PhoneWindowManager 類別 顯示政策、狀態和設定、旋轉、裝飾窗框 追蹤等等Android 10 將大多數這項特色 DisplayPolicy 類別,但不含旋轉追蹤, 已移至 DisplayRotation

顯示視窗設定

在 Android 10 中,可為個別螢幕設定 視窗設定已擴大納入以下內容:

  • 預設顯示視窗模式
  • 過掃描值
  • 使用者旋轉和旋轉模式
  • 強制大小、密度和縮放模式
  • 內容移除模式 (螢幕遭移除時)
  • 支援系統裝飾和輸入法編輯器

DisplayWindowSettings 類別包含這些設定 只要設定成「自動重新啟動」 和「在主機維護期間」選項即可資料表會保留在 /data 分區中 設定每次變更時display_settings.xml。適用對象 詳細資料,請參閱「DisplayWindowSettings.AtomicFileStorage」和 DisplayWindowSettings#writeSettings()。裝置製造商可 在 display_settings.xml 中提供裝置的預設值 此外還會從 0 自動調整資源配置 您完全不必調整資源調度設定但由於檔案儲存在 /data 中, 如果遭抹除作業清除資料,可能需要額外的邏輯才能還原檔案。

根據預設,Android 10 會使用 保存期間,將 DisplayInfo#uniqueId 做為顯示畫面的 ID 但別忘了,應針對所有螢幕填入 uniqueId。於 此外,也要相當穩定地顯示實體螢幕和網路螢幕。您也可以將 使用實體螢幕的通訊埠做為 ID,可在 DisplayWindowSettings#mIdentifier。每次寫入時,所有設定 因此您可以放心更新在 如果 30 天內讀取資料不到一次 建議使用 Coldline Storage詳情請參閱 靜態顯示 ID

設定會保留在 /data 目錄中。 理由。原先已用於保留使用者指定的設定,例如 螢幕旋轉。

靜態顯示 ID

Android 9 (及更低版本) 並未為 這個架構的重點在於在系統中新增螢幕後 Display#mDisplayIdDisplayInfo#displayId 之前為 方法是遞增一個靜態計數器。如果系統 新增了及移除同一個螢幕,但卻產生了不同的 ID。

如果裝置在開機時有多個螢幕,則螢幕可能會 就會根據不同時間指派不同的 IDAndroid 9 之前) 包含 DisplayInfo#uniqueId,回覆數不足 因為實體螢幕 代表 local:0local:1, 內建和外接螢幕

Android 10 變更 DisplayInfo#uniqueId 加入固定 ID,並用來區分區域、聯播網和 虛擬螢幕

顯示類型 格式
地區性
local:<stable-id>
網路
network:<mac-address>
虛擬
virtual:<package-name-and-name>

除了 uniqueId 更新以外, DisplayInfo.address 包含 DisplayAddress, 顯示能在每次重新啟動時保持不變的 ID。在 Android 中 10,DisplayAddress 支援實體 以及網路螢幕DisplayAddress.Physical 包含穩定版 顯示 ID (與 uniqueId 相同),而且可透過 DisplayAddress#fromPhysicalDisplayId()

Android 10 也提供多種便利的方式 通訊埠資訊 (Physical#getPort())。這個方法適用於 靜態識別螢幕的架構例如,在 BigQuery 中 DisplayWindowSettings)。DisplayAddress.Network 包含 MAC 位址,且可透過 DisplayAddress#fromMacAddress()

新增這些額外元素,可讓裝置製造商辨識靜態圖像的 設定多螢幕以及配置不同的系統設定和功能 使用靜態顯示 ID 例如實體螢幕的通訊埠這些 只能於 system_server

假設 HWC 顯示 ID (可能不透明且不一定穩定),這就會有 方法會傳回 (平台專屬) 8 位元通訊埠號碼,以識別 顯示輸出內容的實體連接器,以及螢幕的 EDID blob。 SurfaceFlinger 會從 EDID 擷取製造商或型號資訊 產生向架構公開的穩定 64 位元顯示 ID。如果這個方法 否則 SurfaceFlinger 會改回使用舊版 MD 模式 其中 DisplayInfo#address 為空值。 DisplayInfo#uniqueId 是以硬式編碼的方式寫入,如上所述。

如要確認支援這項功能,請執行以下指令:

$ dumpsys SurfaceFlinger --display-id
# Example output.
Display 21691504607621632 (HWC display 0): port=0 pnpId=SHP displayName="LQ123P1JX32"
Display 9834494747159041 (HWC display 2): port=1 pnpId=HWP displayName="HP Z24i"
Display 1886279400700944 (HWC display 1): port=2 pnpId=AUS displayName="ASUS MB16AP"

使用兩個以上的螢幕

在 Android 9 (及以下版本)、SurfaceFlinger 和 DisplayManagerService 假設有兩個實體螢幕的存在,且硬式編碼 ID 為 0 和 1.

從 Android 10 開始,SurfaceFlinger 可以利用 Hardware Composer (HWC) API 可產生穩定的顯示 ID,以便管理 任意數量的實體螢幕詳情請參閱: 靜態顯示 ID

架構可查詢實體的 IBinder 符記 在取得裝置後透過 SurfaceControl#getPhysicalDisplayToken 顯示 SurfaceControl#getPhysicalDisplayIds 或 在 DisplayEventReceiver 熱壓事件發生時觸發

在 Android 10 以下版本中,主要內部螢幕 TYPE_INTERNAL 和所有次要螢幕均標記為 TYPE_EXTERNAL 輸出流量因此,系統會將其他內部螢幕視為外部螢幕。 解決方法是可以假設裝置專屬程式碼 DisplayAddress.Physical#getPort 表示已知 HWC 以及通訊埠分配 是可預測的

這項限制已在 Android 11 以上版本中移除。

  • 在 Android 11 中,啟動期間回報的第一個螢幕是 主螢幕。連線類型 (內部或外部) 不相關, 然而,主要螢幕無法連線,而且會遵循 必須是實際使用的內部螢幕。請注意,部分摺疊式手機 內建螢幕。
  • 次要螢幕已正確歸類為「Display.TYPE_INTERNAL」 或 Display.TYPE_EXTERNAL (先前稱為 Display.TYPE_BUILT_INDisplay.TYPE_HDMI)。
,瞭解如何調查及移除這項存取權。

實作

在 Android 9 以下版本中,螢幕是以 32 位元 ID 標示 其中 0 是內部螢幕,1 是外接螢幕,[2, INT32_MAX] 是 HWC 虛擬螢幕,-1 代表無效的螢幕或非 HWC 虛擬螢幕。

自 Android 10 起,螢幕會保持穩定 和永久 ID,也就是允許 SurfaceFlinger 和 DisplayManagerService 來追蹤超過兩個螢幕,並辨識先前出現的螢幕。如果 HWC 支援 IComposerClient.getDisplayIdentificationData 並提供螢幕 識別資料,SurfaceFlinger 會剖析 EDID 結構並分配穩定 實體螢幕和 HWC 虛擬顯示器的 64 位元顯示 ID。這些 ID 是以 選項類型,其中空值代表無效的顯示畫面或非 HWC 虛擬 螢幕。如果沒有 HWC 支援,SurfaceFlinger 會依照 最多兩個實體螢幕

個別螢幕焦點

為了支援多個指定單一螢幕的個別螢幕輸入來源 則可以設定 Android 10 支援多種 每個畫面上最多只能聚焦一個視窗。僅適用於特殊用途 多種類型的裝置 (多位使用者可在同一部裝置上進行互動) 使用不同的輸入方式或裝置,例如 Android Automotive。

強烈建議您「不要」替 包括多螢幕裝置或類似電腦的裝置 這點十分重要這主要是基於使用者安全性疑慮, 不知道哪個視窗有輸入焦點

假設使用者在文字輸入欄位中輸入安全資訊, 例如登入銀行應用程式,或是輸入包含 可能不準確或不適當惡意應用程式可能會利用 來處理活動,也具有文字輸入欄位正當與 惡意活動具有專注力,且都會顯示主動輸入指標 (閃爍遊標)。

但因為輸入的 依執行順序由高至低排序 (最近啟動的應用程式) 建立隱藏的虛擬螢幕時,惡意應用程式可能竊取使用者輸入內容 在主要裝置的顯示器上使用螢幕鍵盤時。

使用「com.android.internal.R.bool.config_perDisplayFocusEnabled」 設定個別螢幕焦點

相容性

問題:在 Android 9 以下版本中,最多只會有一個 所以我們只會集中註意力

解決方法:在罕見情況下, 系統只會聚焦於相同程序,只會聚焦於視窗本身 這個順序也在 Z 順序上這項限制已針對指定的應用程式解除 就 Android 10 而言, 支援多個視窗同時專注。

實作

WindowManagerService#mPerDisplayFocusEnabled 控管 可用性。在 ActivityManager, 現已使用 ActivityDisplay#getFocusedStack(),而非全域 變數追蹤ActivityDisplay#getFocusedStack() 會根據 Z 順序來決定焦點,而不是快取值。如此一來 只有一個來源 (WindowManager) 需要追蹤活動的 Z 順序。

ActivityStackSupervisor#getTopDisplayFocusedStack(): 類似做法。 。系統會由上至下穿越堆疊,並搜尋 第一個符合資格的堆疊

InputDispatcher現在可以有多個聚焦視窗 (每個多媒體廣告一個)。如果輸入事件僅適用於螢幕,就會分派 在相應畫面的聚焦視窗中。否則會 並將焦點移到焦點所在的畫面,也就是使用者看到的畫面 最近互動的使用者

請參閱InputDispatcher::mFocusedWindowHandlesByDisplayInputDispatcher::setFocusedDisplay()。焦點應用程式也會更新 接著在 InputManagerService 中分別執行 NativeInputManager::setFocusedApplication()

WindowManager 中,系統也會分別追蹤聚焦的視窗。 請參閱DisplayContent#mCurrentFocusDisplayContent#mFocusedApp 和個別用途。相關重點 追蹤及更新方法 WindowManagerServiceDisplayContent