行為變更:指定 Android 16 以上版本的應用程式

和先前版本一樣,Android 16 也包含可能會影響應用程式的行為變更。以下行為變更僅適用於指定 Android 16 以上版本的應用程式。如果應用程式指定 Android 16 以上版本,建議您視情況修改應用程式,以支援這些行為。

此外,無論應用程式的 targetSdkVersion 為何,請務必查看對所有 Android 16 應用程式有影響的行為變更清單。

使用者體驗和系統 UI

Android 16 (API 級別 36) 包含下列變更,旨在打造更一致、直覺的使用者體驗。

無邊框顯示選擇不採用選項即將移除

Android 15 強制要求指定 Android 15 (API 級別 35) 的應用程式採用無邊框設計,但應用程式可以將 R.attr#windowOptOutEdgeToEdgeEnforcement 設為 true,選擇不採用這項設計。如果應用程式指定 Android 16 (API 級別 36) 為目標,R.attr#windowOptOutEdgeToEdgeEnforcement 會遭到淘汰並停用,且應用程式無法選擇不採用無邊框模式。

  • 如果應用程式指定 Android 16 (API 級別 36) 為目標版本,且在 Android 15 裝置上執行,R.attr#windowOptOutEdgeToEdgeEnforcement 會繼續運作。
  • 如果應用程式指定 Android 16 (API 級別 36) 為目標,並在 Android 16 裝置上執行,系統會停用 R.attr#windowOptOutEdgeToEdgeEnforcement。

如要在 Android 16 進行測試,請確保應用程式支援無邊框模式,並移除所有 R.attr#windowOptOutEdgeToEdgeEnforcement 的使用,讓應用程式在 Android 15 裝置上也支援無邊框模式。如要支援無邊框,請參閱 Compose 和檢視畫面指南。

必須遷移或選擇不採用預測返回

如果應用程式指定 Android 16 (API 級別 36) 以上版本,且在搭載 Android 16 以上版本的裝置上執行,系統預設會啟用預測返回系統動畫 (返回主畫面、跨任務和跨活動)。此外,系統不會呼叫 onBackPressed,也不會再調度 KeyEvent.KEYCODE_BACK。

如果應用程式會攔截返回事件,且您尚未遷移至預測返回手勢,請更新應用程式,改用支援的返回瀏覽 API,或暫時停用這項功能,方法是在應用程式 AndroidManifest.xml 檔案的 <application> 或 <activity> 標記中,將 android:enableOnBackInvokedCallback 屬性設為 false。

預測返回主畫面動畫。
預測跨活動動畫。
預測跨任務動畫。

Elegant 字型 API 已淘汰並停用

指定 Android 15 (API 級別 35) 的應用程式會預設將 elegantTextHeight TextView 屬性設為 true,以更易於閱讀的字型取代精簡字型。您可以將 elegantTextHeight 屬性設為 false,藉此覆寫這項設定。

Android 16 會淘汰 elegantTextHeight 屬性,應用程式指定 Android 16 後,系統就會忽略該屬性。這些 API 控制的「UI 字型」即將停用,因此請調整所有版面配置,確保阿拉伯文、寮文、緬甸文、泰米爾文、古吉拉特文、卡納達文、馬拉雅拉姆文、奧里亞文、泰盧固文或泰文的文字顯示方式一致,且日後不會出錯。

針對指定 Android 14 (API 級別 34) 以下版本的應用程式,或指定 Android 15 (API 級別 35) 但將 elegantTextHeight 屬性設為 false,藉此覆寫預設行為的應用程式,
elegantTextHeight 行為如下:
如果應用程式指定 Android 16 (API 級別 36),或指定 Android 15 (API 級別 35) 但未將 elegantTextHeight 屬性設為 false 來覆寫預設值,則會採用
elegantTextHeight 行為。

核心功能

Android 16 (API 級別 36) 包含下列異動項目,這類變更會修改或擴充 Android 系統的各種核心功能。

固定費率工作排程最佳化

在指定 Android 16 之前,如果 scheduleAtFixedRate 因不在有效的程序生命週期中而錯過執行工作,則應用程式返回有效生命週期時,所有錯過的執行作業會立即執行。

針對 Android 16 進行指定時,應用程式返回有效生命週期時,最多會立即執行 一次遺漏的 scheduleAtFixedRate 執行作業。這項行為異動預計可改善應用程式效能。在應用程式中測試這項行為,確認應用程式是否受到影響。您也可以使用應用程式相容性架構,並啟用 STPE_SKIP_MULTIPLE_MISSED_PERIODIC_TASKS 相容性標記來進行測試。

裝置板型規格

Android 16 (API 級別 36) 包含下列變更,適用於在大螢幕裝置上顯示的應用程式。

自動調整式版面配置

Android 應用程式現在可在各種裝置 (例如手機、平板電腦、折疊式裝置、電腦、車輛和電視) 上執行,並在大螢幕上支援多種視窗模式 (例如分割畫面和電腦視窗模式),因此開發人員應建構可適應任何螢幕和視窗大小的 Android 應用程式,無論裝置方向為何。在現今的多裝置世界中,限制螢幕方向和大小調整等模式過於嚴格。

忽略螢幕方向、可調整大小和顯示比例限制

如果應用程式指定 Android 16 (API 級別 36),則在最小寬度 >= 600dp 的螢幕上,不再適用螢幕方向、大小調整和顯示比例限制。無論顯示比例或使用者偏好的螢幕方向為何,應用程式都會填滿整個顯示視窗,且不會使用左右黑邊。

這項異動會導入新的標準平台行為。Android 正在轉向一種模式,讓應用程式能適應各種螢幕方向、顯示大小和顯示比例。固定螢幕方向或限制大小調整等限制,會阻礙應用程式的適應性。讓應用程式具備自動調整功能,提供最佳使用者體驗。

您也可以使用應用程式相容性架構,並啟用 UNIVERSAL_RESIZABLE_BY_DEFAULT 相容性旗標,測試這項行為。

常見破壞性變更

忽略螢幕方向、大小調整和顯示比例限制,可能會影響應用程式在某些裝置上的 UI,尤其是專為鎖定直向的小型版面配置設計的元素,例如版面配置拉伸、動畫和元件超出螢幕範圍等問題。對顯示比例或螢幕方向的任何假設,都可能導致應用程式出現視覺問題。進一步瞭解如何避免這些問題,並改善應用程式的自動調整行為。

允許裝置旋轉會導致更多活動重新建立,如果未妥善保留,可能會遺失使用者狀態。如要瞭解如何正確儲存 UI 狀態,請參閱「儲存 UI 狀態」。

實作詳細資料

在全螢幕和多視窗模式下,大螢幕裝置會忽略下列資訊清單屬性和執行階段 API:

系統會忽略 screenOrientation、setRequestedOrientation() 和 getRequestedOrientation() 的下列值:

  • portrait
  • reversePortrait
  • sensorPortrait
  • userPortrait
  • landscape
  • reverseLandscape
  • sensorLandscape
  • userLandscape

android:resizeableActivity="false"、android:minAspectRatio 和 android:maxAspectRatio 對顯示大小調整功能沒有影響。

如果應用程式指定 Android 16 (API 級別 36),系統預設會在大螢幕上忽略應用程式的方向、大小調整和顯示比例限制。如果應用程式尚未完全準備就緒,可以選擇停用這項功能,暫時覆寫這項行為,這樣就會像先前一樣,進入相容模式。

例外狀況

Android 16 的螢幕方向、大小調整和顯示比例限制不適用於下列情況:

  • 遊戲 (根據 android:appCategory 旗標)
  • 使用者在裝置的顯示比例設定中,明確選擇採用應用程式的預設行為
  • 小於 sw600dp 的螢幕

暫時退出

如要停用特定活動,請宣告 PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY 資訊清單屬性:

<activity ...>
  <property android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY" android:value="true" />
  ...
</activity>

如果應用程式有太多部分尚未準備好支援 Android 16,您可以在應用程式層級套用相同屬性,完全停用這項功能:

<application ...>
  <property android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY" android:value="true" />
</application>

健康與健身

Android 16 (API 級別 36) 包含下列與健康和運動資料相關的異動。

健康與健身權限

如果應用程式指定 Android 16 (API 級別 36) 以上版本,BODY_SENSORS 權限會使用 android.permissions.health 下更精細的權限,健康資料同步 也會使用這些權限。自 Android 16 起,凡是先前需要 BODY_SENSORS 或 BODY_SENSORS_BACKGROUND 的 API,現在都需要對應的 android.permissions.health 權限。這會影響下列資料類型、API 和前景服務類型:

如果應用程式使用這些 API,應要求相應的精細權限:

這些權限與保護 Health Connect (Android 健康、健身和保健資料儲存庫) 資料讀取權限的權限相同。

行動應用程式

如果行動應用程式改用 READ_HEART_RATE 和其他精細權限,也必須宣告活動,顯示應用程式的隱私權政策。這項規定與「健康資料同步」相同。

連線能力

Android 16 (API 級別 36) 包含下列藍牙堆疊變更,可改善與周邊裝置的連線能力。

處理繫結遺失和加密變更的新意圖

除了改善連結遺失處理功能,Android 16 也推出了 2 個新的意圖,讓應用程式更能察覺連結遺失和加密變更。

鎖定 Android 16 的應用程式現在可以:

  • 在偵測到遠端連結中斷時接收 ACTION_KEY_MISSING 意圖,以便提供更有用的使用者意見回饋,並採取適當行動。
  • 每當連結的加密狀態變更時,就會收到 ACTION_ENCRYPTION_CHANGE 意圖。包括加密狀態變更、加密演算法變更和加密金鑰大小變更。如果應用程式稍後收到 ACTION_ENCRYPTION_CHANGE 意圖,且連結已成功加密,則必須考慮恢復連結。

因應不同原始設備製造商 (OEM) 實作

雖然 Android 16 推出了這些新意圖,但不同裝置製造商 (OEM) 的實作和廣播方式可能有所不同。為確保應用程式可在所有裝置上提供一致且可靠的體驗,開發人員應設計連結中斷處理機制,以便妥善因應這些潛在的變化。

我們建議您採用下列應用程式行為:

  • 如果廣播 ACTION_KEY_MISSING 意圖:

    系統會中斷 ACL (非同步無連結) 連結,但會保留裝置的連結資訊 (如這裡所述)。

    應用程式應使用這個意圖做為偵測連結中斷的主要信號,並在啟動裝置忘記或重新配對功能前,引導使用者確認遠端裝置是否在範圍內。

    如果裝置在收到 ACTION_KEY_MISSING 後中斷連線,應用程式應謹慎重新連線,因為裝置可能已不再與系統綁定。

  • 如果 ACTION_KEY_MISSING 意圖未廣播:

    ACL 連結會保持連線狀態,系統會移除裝置的連結資訊,這與 Android 15 的行為相同。

    在這種情況下,應用程式應繼續使用與先前 Android 版本相同的現有連結失效處理機制,以偵測及管理連結失效事件。

移除藍牙繫結的新方法

所有以 Android 16 為目標版本的應用程式,現在都能使用 CompanionDeviceManager 中的公開 API 解除配對藍牙裝置。如果隨附裝置是以 CDM 關聯方式管理,應用程式可以在關聯裝置上使用新的 removeBond(int) API 觸發藍牙連結移除作業。應用程式可以監控連結狀態變更,方法是監聽藍牙裝置廣播事件 ACTION_BOND_STATE_CHANGED。

安全性

Android 16 (API 級別 36) 包含下列安全性異動。

MediaStore 版本鎖定

針對指定 Android 16 以上版本的應用程式,MediaStore#getVersion() 現已成為每個應用程式的專屬值。這麼做可移除版本字串中的識別屬性,以免遭到濫用,並防止用於指紋辨識技術。應用程式不應對此版本的格式做出任何假設。應用程式在使用此 API 時應已處理版本變更,且在大多數情況下,不必變更目前的行為,除非開發人員嘗試推斷超出此 API 預期範圍的其他資訊。

更安全的意圖

Safer Intents 功能是一項多階段安全性計畫,旨在提升 Android 意圖解析機制的安全性。目的是在處理意圖時加入檢查,並篩除不符合特定條件的意圖,保護應用程式免受惡意行為影響。

在 Android 15 中,這項功能著重於傳送應用程式。現在,Android 16 將控制權轉移至接收應用程式,開發人員可使用應用程式資訊清單,選擇加入嚴格意圖解析。

我們將實施兩項重大異動:

  1. 明確意圖必須與目標元件的意圖篩選器相符:如果意圖明確指定某個元件,則應與該元件的意圖篩選器相符。

  2. 沒有動作的意圖無法比對任何意圖篩選器:未指定動作的意圖不應解析至任何意圖篩選器。

這些變更僅適用於涉及多個應用程式的情況,不會影響單一應用程式中的意圖處理。

影響

由於這項功能需要選擇加入,開發人員必須在應用程式資訊清單中明確啟用,才能生效。因此,這項功能只會影響開發人員符合下列條件的應用程式:

  • 瞭解 Safer Intents 功能及其優點。
  • 主動選擇在應用程式中採用更嚴格的意圖處理做法。

這種選擇加入的做法可盡量降低風險,避免現有應用程式因依賴目前安全性較低的意圖解析行為而中斷。

雖然 Android 16 的初期影響可能有限,但 Safer Intents 計畫已制定藍圖,未來將在 Android 版本中擴大影響範圍。我們預計最終會將嚴格意圖解析設為預設行為。

Safer Intents 功能可提高惡意應用程式利用意圖解析機制漏洞的難度,大幅提升 Android 生態系統的安全性。

不過,轉換至選擇不採用和強制執行時,必須謹慎管理,以解決現有應用程式可能發生的相容性問題。

導入作業

開發人員必須在應用程式資訊清單中使用 intentMatchingFlags 屬性,明確啟用更嚴格的意圖比對。以下範例說明如何為整個應用程式選擇加入這項功能,但對接收器停用/選擇不採用:

<application android:intentMatchingFlags="enforceIntentFilter">
    <receiver android:name=".MyBroadcastReceiver" android:exported="true" android:intentMatchingFlags="none">
        <intent-filter>
            <action android:name="com.example.MY_CUSTOM_ACTION" />
        </intent-filter>
        <intent-filter>
            <action android:name="com.example.MY_ANOTHER_CUSTOM_ACTION" />
        </intent-filter>
    </receiver>
</application>

進一步瞭解支援的旗標:

旗標名稱 說明
enforceIntentFilter 對傳入意圖強制執行更嚴格的比對
無 停用傳入意圖的所有特殊比對規則。指定多個旗標時,系統會優先採用「none」旗標,解決值衝突的問題
allowNullAction 放寬比對規則,允許沒有動作的意圖進行比對。這個旗標應與「enforceIntentFilter」搭配使用,以達到特定行為

測試和偵錯

強制執行生效後,如果意圖呼叫端已正確填入意圖,應用程式應可正常運作。不過,遭封鎖的意圖會觸發警告記錄訊息,例如 "Intent does not match component's intent filter:" 和 "Access blocked:",並加上 "PackageManager." 標記。這表示可能存在會影響應用程式的問題,需要注意。

Logcat 篩選器:

tag=:PackageManager & (message:"Intent does not match component's intent filter:" | message: "Access blocked:")

GPU 系統呼叫篩選

為強化 Mali GPU 介面,正式版建構作業已封鎖已淘汰或僅用於 GPU 開發的 Mali GPU IOCTL。此外,用於 GPU 分析的 IOCTL 已限制為殼層程序或可進行偵錯的應用程式。如要進一步瞭解平台層級政策,請參閱 SAC 更新。

這項異動適用於使用 Mali GPU 的 Pixel 裝置 (Pixel 6-9)。Arm 已在 r54p2 版本的 Documentation/ioctl-categories.rst 中提供 IOCTL 的官方分類。日後推出的驅動程式版本會繼續維護這份清單。

這項異動不會影響支援的圖形 API (包括 Vulkan 和 OpenGL),預計也不會影響開發人員或現有應用程式。Streamline Performance Analyzer 和 Android GPU 檢查器等 GPU 分析工具則不受影響。

測試

如果看到類似下方的 SELinux 拒絕訊息,代表應用程式可能受到這項異動影響:

06-30 10:47:18.617 20360 20360 W roidJUnitRunner: type=1400 audit(0.0:85): avc:  denied  { ioctl }
for  path="/dev/mali0" dev="tmpfs" ino=1188 ioctlcmd=0x8023
scontext=u:r:untrusted_app_25:s0:c512,c768 tcontext=u:object_r:gpu_device:s0 tclass=chr_file
permissive=0 app=com.google.android.selinux.pts

如果應用程式需要使用遭封鎖的 IOCTL,請回報錯誤,並指派給 android-partner-security@google.com。

常見問題

  1. 這項政策異動是否適用於所有原始設備製造商? 這項變更可選擇加入,但任何想使用這種強化方法的原始設備製造商 (OEM) 都能使用。如需導入這項異動的操作說明,請參閱導入說明文件。

  2. 是否必須變更原始設備製造商 (OEM) 程式碼集才能實作這項功能,還是新版 AOSP 預設會提供這項功能?根據預設,平台層級的變更會隨新的 AOSP 版本推出。如果供應商想套用這項變更,可以選擇在程式碼集中加入。

  3. SoC 是否負責更新 IOCTL 清單?舉例來說,如果我的裝置使用 ARM Mali GPU,是否需要與 ARM 聯絡才能進行任何變更? 個別 SoC 必須在驅動程式發布時,更新每個裝置的 IOCTL 清單。舉例來說,ARM 會在驅動程式更新時,更新已發布的 IOCTL 清單。不過,原始設備製造商 (OEM) 應確保將更新內容納入 SEPolicy,並視需要將任何選取的自訂 IOCTL 新增至清單。

  4. 這項異動會自動套用至所有市售 Pixel 裝置嗎?還是使用者需要手動切換設定才能套用? 這項異動適用於所有使用 Mali GPU 的 Pixel 市售裝置 (Pixel 6-9)。使用者無須採取任何行動,即可套用這項變更。

  5. 使用這項政策是否會影響核心驅動程式的效能? 這項政策已在 Mali GPU 上使用 GFXBench 進行測試,並未觀察到 GPU 效能有任何可測量的變化。

  6. IOCTL 清單是否必須與目前的使用者空間和核心驅動程式版本一致? 是的,允許的 IOCTL 清單必須與使用者空間和核心驅動程式支援的 IOCTL 同步。如果使用者空間或核心驅動程式中的 IOCTL 有更新,SEPolicy IOCTL 清單也必須一併更新。

  7. ARM 已將 IOCTL 分類為「受限」/「檢測」,但我們想在實際工作環境用途中使用部分 IOCTL,和/或拒絕其他 IOCTL。 個別原始設備製造商 (OEM)/SoC 負責根據使用者空間 Mali 程式庫的設定,決定如何分類使用的 IOCTL。ARM 的清單可用於協助決定這些項目,但每個原始設備製造商 (OEM)/SoC 的用途可能不同。

隱私權

Android 16 (API 級別 36) 包含下列隱私權異動。

區域網路權限

凡具備 INTERNET 權限的應用程式,都能存取 LAN 上的裝置。雖然應用程式可因此輕鬆連線到本機裝置,但也帶來隱私疑慮,例如建立使用者數位指紋,或成為推算位置資訊的依據。

區域網路保護措施專案旨在保護使用者隱私,因此會透過新的執行階段權限,限制對區域網路的存取。

發布計畫

這項異動將分兩階段實施,分別在 25Q2 和 26Q2。開發人員務必遵循 25Q2 的指引並提供意見回饋,因為這些保護措施將在日後的 Android 版本中強制執行。此外,他們需要按照下列指南,更新依賴隱含區域網路存取權的情境,並做好使用者拒絕和撤銷新權限的準備。

影響

目前,LNP 是選擇性功能,也就是說,只有選擇加入的應用程式會受到影響。選擇加入階段的目標是讓應用程式開發人員瞭解應用程式的哪些部分依賴隱含的區域網路存取權,以便為下一個版本做好權限防護準備。

如果應用程式使用下列項目存取使用者的區域網路,就會受到影響:

  • 直接或透過程式庫使用區域網路位址上的原始通訊端 (例如 mDNS 或 SSDP 服務探索通訊協定)
  • 使用存取區域網路的架構層級類別 (例如 NsdManager)

傳送至和來自區域網路位址的流量,需要區域網路存取權限。下表列出一些常見情況:

應用程式低層級網路作業 必須授予區域網路權限
建立傳出 TCP 連線 是
接受傳入的 TCP 連線 是
傳送 UDP 單點傳播、多點傳播、廣播 是
接收傳入的 UDP 單點傳播、多點傳播、廣播 是

這些限制是在網路堆疊深處實施,因此適用於「所有網路 API」。這包括在原生或代管程式碼中建立的通訊端、Cronet 和 OkHttp 等網路程式庫,以及在這些程式庫上實作的任何 API。如要解析區域網路上的服務 (即後置字串為 .local 的服務),則需要區域網路權限。

上述規則的例外狀況:

  • 如果裝置的 DNS 伺服器位於區域網路,則往返該伺服器的流量 (通訊埠 53) 不需要區域網路存取權限。
  • 如果應用程式使用輸出切換器做為應用程式內選擇器,就不需要區域網路權限 (2025 年第 4 季會提供更多指引)。

開發人員指南 (選擇加入)

如要啟用區域網路限制,請按照下列步驟操作:

  1. 將裝置刷寫至 25Q2 Beta 3 以上版本。
  2. 安裝要測試的應用程式。
  3. 在 ADB 中切換 Appcompat 旗標:

    adb shell am compat enable RESTRICT_LOCAL_NETWORK <package_name>
    
  4. 重新啟動裝置

現在,應用程式對區域網路的存取權已受限,任何嘗試存取區域網路的行為都會導致通訊端錯誤。如果您使用的 API 會在應用程式程序外執行區域網路作業 (例如 NsdManager),在選擇加入階段不會受到影響。

如要恢復存取權,請授予應用程式NEARBY_WIFI_DEVICES權限。

  1. 確認應用程式在資訊清單中宣告 NEARBY_WIFI_DEVICES 權限。
  2. 依序前往「設定」>「應用程式」> [應用程式名稱] >「權限」>「鄰近裝置」>「允許」。

現在,應用程式應可重新存取區域網路,且所有情境都應能正常運作,就像在應用程式啟用這項功能之前一樣。

區域網路保護措施開始強制執行後,應用程式網路流量會受到以下影響。

權限 傳出 LAN 要求 傳出/傳入網際網路要求 傳入 LAN 要求
已授予 Works Works Works
未授予 凸槌影片 Works 凸槌影片

使用下列指令關閉 App-Compat 旗標

adb shell am compat disable RESTRICT_LOCAL_NETWORK <package_name>

錯誤

每當呼叫通訊端叫用傳送或傳送變體至區域網路位址時,系統會將這些限制引起的錯誤傳回給呼叫通訊端。

錯誤示例:

sendto failed: EPERM (Operation not permitted)

sendto failed: ECONNABORTED (Operation not permitted)

區域網路定義

這項專案中的區域網路是指使用具備廣播功能網路介面 (例如 Wi-Fi 或乙太網路) 的 IP 網路,但不包括行動網路 (WWAN) 或 VPN 連線。

下列網路視為區域網路:

IPv4:

  • 169.254.0.0/16 // 連結本機
  • 100.64.0.0/10 // CGNAT
  • 10.0.0.0/8 // RFC1918
  • 172.16.0.0/12 // RFC1918
  • 192.168.0.0/16 // RFC1918

IPv6:

  • 連結至本機
  • 直接連結的路徑
  • Thread 等虛設常式網路
  • 多子網路 (待定)

此外,多點傳播位址 (224.0.0.0/4、ff00::/8) 和 IPv4 廣播地址 (255.255.255.255) 都歸類為區域網路位址。

應用程式擁有的相片

當指定 SDK 36 以上版本的應用程式在搭載 Android 16 以上版本的裝置上執行時,如果系統提示使用者授予相片和影片權限,選擇限制所選媒體存取權的使用者會在相片挑選器中看到應用程式預先選取的所有相片。使用者可以取消選取任何預先選取的項目,這樣一來,應用程式就無法存取這些相片和影片。