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

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

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

使用者體驗和系統使用者介面

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 Beta 版 3 中进行测试,请确保您的应用支持无边框设计,并移除对 R.attr#windowOptOutEdgeToEdgeEnforcement 的所有使用,以便您的应用在 Android 15 设备上也支持无边框设计。如需支持边到边,请参阅 ComposeViews 指南。

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

如果應用程式指定 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 控制的“界面字体”即将停用,因此您应调整所有布局,以确保以阿拉伯语、老挝语、缅甸语、泰米尔语、古吉拉特语、卡纳达语、马拉雅拉姆语、奥里亚语、泰卢固语或泰语呈现一致且可持续的文字。

对于以 Android 14(API 级别 34)及更低版本为目标平台的应用,或者对于以 Android 15(API 级别 35)为目标平台且通过将 elegantTextHeight 属性设为 false 替换了默认值的应用,elegantTextHeight 行为。
对于以 Android 16 为目标平台的应用,或者对于未通过将 elegantTextHeight 属性设置为 false 来替换默认值的以 Android 15(API 级别 35)为目标平台的应用,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),Android 16 會針對系統管理方向、大小調整和顯示比例限制的方式進行變更。在最小寬度大於等於 600 dp 的螢幕上,系統就不會再套用這些限制。無論顯示比例或使用者偏好的螢幕方向為何,應用程式都會填滿整個顯示視窗,且不會使用上下黑邊。

這項變更會引入新的標準平台行為。Android 正朝向新模型邁進,應用程式應能根據各種方向、螢幕大小和顯示比例自動調整。固定螢幕方向或限制尺寸調整功能等限制會影響應用程式的適應性,因此建議讓應用程式具備適應性,以便提供最佳使用者體驗。

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

常見的破壞性變更

忽略方向、可調整大小和顯示比例限制,可能會影響部分裝置上的應用程式 UI,尤其是針對小型版面配置設計的元素,因為這些元素會鎖定在直向方向:例如,會導致版面配置拉長、畫面外動畫和元件等問題。任何有關顯示比例或方向的假設都可能導致應用程式出現視覺問題。請參閱這篇文章,進一步瞭解如何避免這些問題,並改善應用程式的自適應行為。

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

導入作業詳細資料

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

系統會忽略下列 screenOrientationsetRequestedOrientation()getRequestedOrientation() 的值:

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

就螢幕可調整大小而言,android:resizeableActivity="false"android:minAspectRatioandroid: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 下更精細的權限,而 Health Connect 也會使用這些權限。自 Android 16 起,凡是先前需要 BODY_SENSORSBODY_SENSORS_BACKGROUND 的 API,現在都需要對應的 android.permissions.health 權限。這會影響下列資料類型、API 和前景服務類型:

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

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

行動應用程式

行動應用程式如果遷移至使用 READ_HEART_RATE 和其他精細權限,也必須宣告活動,才能顯示應用程式的隱私權政策。這項規定與 Health Connect 相同。

連線能力

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

處理失效連結和加密變更的新意圖

作为改进了对键值对丢失的处理的一部分,Android 16 还引入了 2 个新 intent,以便应用更好地了解键值对丢失和加密更改。

以 Android 16 为目标平台的应用现在可以:

  • 在检测到远程键盘连接丢失时接收 ACTION_KEY_MISSING intent,以便提供更具信息量的用户反馈并采取适当的措施。
  • 每当链接的加密状态发生变化时,都会收到 ACTION_ENCRYPTION_CHANGE intent。这包括加密状态更改、加密算法更改和加密密钥大小更改。如果应用在稍后收到 ACTION_ENCRYPTION_CHANGE intent 时成功加密了链接,则必须将该绑定视为已恢复。

适应不同的 OEM 实现

虽然 Android 16 引入了这些新 intent,但其实现和广播可能会因不同的设备制造商 (OEM) 而异。为了确保您的应用在所有设备上都能提供一致且可靠的体验,开发者应设计其绑定丢失处理机制,以妥善适应这些潜在的变化。

我们建议您采用以下应用行为:

  • 如果广播 ACTION_KEY_MISSING intent:

    系统会断开 ACL(异步无连接)链接,但会保留设备的配对信息(如此处所述)。

    您的应用应将此 intent 用作检测配对丢失的主要信号,并在发起设备忘记或重新配对之前引导用户确认远程设备是否在范围内。

    如果设备在收到 ACTION_KEY_MISSING 后断开连接,您的应用应谨慎重新连接,因为设备可能已不再与系统绑定。

  • 如果未广播 ACTION_KEY_MISSING intent:

    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 预期范围的其他信息。

更安全的意圖

“更安全的 intent”功能是一项分阶段的安全计划,旨在提高 Android intent 解析机制的安全性。该目标是通过在 intent 处理期间添加检查并过滤不符合特定条件的 intent,保护应用免受恶意操作的侵害。

Android 15 中,该功能侧重于发送应用,而现在在 Android 16 中,该功能将控制权转移给接收应用,让开发者可以选择使用应用清单启用严格的 intent 解析。

我们将实施以下两项重大变更:

  1. 显式 intent 必须与目标组件的 intent 过滤器相匹配:如果 intent 明确定位到某个组件,则应与该组件的 intent 过滤器相匹配。

  2. 没有操作的 intent 无法与任何 intent 过滤器匹配:未指定操作的 intent 不应解析为任何 intent 过滤器。

这些更改仅适用于涉及多个应用的情况,不会影响单个应用内的 intent 处理。

影响

这种“用户选择启用”的特性意味着,开发者必须在应用清单中明确启用该功能,才能使其生效。因此,只有开发者符合以下条件的应用会受到该功能的影响:

  • 了解“更安全的 intent”功能及其优势。
  • 主动选择在应用中采用更严格的 intent 处理做法。

这种“用户选择接受”方法可最大限度地降低破坏可能依赖于当前安全性较低的 intent 解析行为的现有应用的风险。

虽然在 Android 16 中的初始影响可能有限,但“更安全的 intent”计划制定了路线图,以便在未来的 Android 版本中产生更广泛的影响。我们的计划是最终将严格的 intent 解析作为默认行为。

通过提高恶意应用利用 intent 解析机制中的漏洞的难度,更安全的 intent 功能有望显著增强 Android 生态系统的安全性。

不过,必须谨慎管理向“用户选择拒绝才无效”和强制执行过渡,以解决与现有应用的潜在兼容性问题。

实现

开发者需要在应用清单中使用 intentMatchingFlags 属性明确启用更严格的 intent 匹配。以下示例展示了如何为整个应用选择启用该功能,但在接收器上停用/选择停用该功能:

<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 对传入 intent 强制执行更严格的匹配
none 停用针对传入 intent 的所有特殊匹配规则。指定多个标志时,系统会通过将“none”标志的优先级设为最高来解析冲突的值
allowNullAction 放宽匹配规则,以允许没有匹配操作的 intent。此标志应与“enforceIntentFilter”结合使用,以实现特定行为

测试和调试

强制执行生效后,如果 intent 调用方已正确填充 intent,应用应能正常运行。不过,被屏蔽的 intent 会触发带有标记 "PackageManager." 的警告日志消息,例如 "Intent does not match component's intent filter:""Access blocked:"。这表示可能存在影响应用且需要注意的潜在问题。

Logcat 过滤条件:

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

隱私權

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

區域網路權限

任何具備 INTERNET 權限的應用程式,都可以存取區域網路上的裝置。這麼做可讓應用程式輕鬆連線至本機裝置,但也會影響隱私權,例如形成使用者的指紋,以及成為位置資訊的代理程式。

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

發布計畫

這項異動將分別在 25Q2 和 TBD 兩個版本之間部署。開發人員必須遵循這項 25Q2 指南並提供意見回饋,因為這些防護措施將在後續 Android 版本中強制執行。此外,他們還需要根據下列指南更新依賴隱含本機網路存取權的情況,並為使用者拒絕和撤銷新權限做好準備。

影響

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

如果應用程式使用以下方式存取使用者的本機網路,就會受到影響:

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

區域網路位址的流量,需要區域網路存取權。下表列出一些常見的情況:

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

這些限制是在網路堆疊中深層實作,因此適用於所有網路 API。這包括在原生或受管理程式碼中建立的通訊端,Cronet 和 OkHttp 等網路程式庫,以及在這些項目上實作的任何 API。嘗試解析區域網路上的服務 (也就是具有 .local 後置字元的服務) 時,必須具備區域網路權限。

上述規則的例外狀況:

  • 如果裝置的 DNS 伺服器位於區域網路中,則進出該伺服器的流量 (在通訊埠 53) 不需要區域網路存取權。
  • 使用 Output Switcher 做為應用程式內挑選器的應用程式不需要區域網路權限 (2025Q4 將提供更多指引)。

開發人員指南 (選擇採用)

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

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

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

應用程式現在無法存取區域網路,任何嘗試存取區域網路的動作都會導致通訊端錯誤。如果您使用的是可在應用程式程序外執行本機網路作業的 API (例如 NsdManager),這些 API 在選擇加入階段不會受到影響。

如要恢復存取權,您必須授予應用程式 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>

錯誤

只要呼叫端的通訊端點對本機網路位址呼叫 send 或 send 變數,就會傳回因這些限制而發生的錯誤。

錯誤示例:

sendto failed: EPERM (Operation not permitted)

sendto failed: ECONNABORTED (Operation not permitted)

區域網路定義

本專案中的本機網路是指使用可廣播網路介面的 IP 網路,例如 Wi-Fi 或乙太網路,但不包含行動網路 (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 或更高版本的设备上提示用户授予照片和视频权限时,如果用户选择限制对所选媒体的访问权限,则会在照片选择器中看到该应用拥有的所有照片。用户可以取消选择任何这些预选项,这会撤消该应用对这些照片和视频的访问权限。