Android 17 平台包含可能對應用程式造成影響的行為變更。無論 targetSdkVersion 為何,凡是在 Android 17 上執行的應用程式,「一律」都會受到下列行為變更所影響。您必須測試自己的應用程式,並視需要進行修改,以便在適當情況下支援這些變更。
另請務必查看僅對指定 Android 17 為目標版本的應用程式造成影響的行為變更。
核心功能
Android 17 (API 級別 37) 包含下列異動項目,這類變更會修改或擴充 Android 系統的各種核心功能。
應用程式記憶體限制
Android 17 引入了基于设备总 RAM 的应用内存限制,旨在为您的应用和 Android 用户打造更稳定、更具确定性的环境。在 Android 17 中,限制设置得较为保守,目的是建立系统基准,在极端内存泄漏和其他异常情况触发系统范围的不稳定性(导致界面卡顿、耗电过快和应用被终止)之前,先针对这些情况。虽然我们预计对绝大多数 应用会话的影响很小,但我们建议遵循以下内存最佳实践, 包括建立内存基准。
您可以通过在 ApplicationExitInfo 中调用
getDescription 来确定应用会话是否受到影响;如果您的应用受到
影响,退出原因将为 REASON_OTHER 并且
说明将包含字符串 "MemoryLimiter:AnonSwap" 以及
其他信息。您还可以使用 基于触发器的分析(使用
TRIGGER_TYPE_ANOMALY)来获取在达到
内存限制时收集的堆转储。
为了帮助您查找内存泄漏,Android Studio Panda 直接在 Android Studio 性能分析器中添加了 LeakCanary 集成,作为 IDE 中特定任务,并与您的源代码完全集成。
隱私權
Android 17 包含下列異動項目,可提升使用者隱私權。
簡訊動態密碼防護
從 Android 17 開始,Android 將擴大對含有動態密碼 (OTP) 的簡訊提供保護。
在舊版 Android 中,這項保護措施主要著重於簡訊擷取器格式。含有簡訊擷取器雜湊值的訊息傳送作業延遲了三小時,大多數應用程式都受到影響。不過,某些應用程式 (例如預設 SMS 處理常式) 可免除延遲,擁有雜湊的應用程式也適用這項豁免。
從 Android 17 開始,這項保護措施也適用於 WebOTP 格式的訊息。如果應用程式有權讀取簡訊,但並非 WebOTP 訊息的預期收件者 (由網域驗證決定),應用程式必須等到收到訊息三小時後,才能存取該訊息。這項異動的目的是提升使用者安全性,確保只有與訊息中提及的網域相關聯的應用程式,才能以程式輔助方式讀取驗證碼。
在這三小時的延遲期間,SMS_RECEIVED_ACTION 廣播會暫緩,且 SMS 供應商資料庫查詢會經過篩選。延遲後,這些應用程式就能存取簡訊。這項異動適用於所有應用程式,無論目標 API 級別為何。
預設訊息助理應用程式、連結裝置的隨附應用程式等特定應用程式,則不受這項延遲限制。如果應用程式需要讀取簡訊來擷取動態密碼,請改用 SMS Retriever 或 SMS User Consent API,確保功能不受影響。
安全性
Android 17 包含下列裝置和應用程式安全防護改善項目。
usesClearTraffic 淘汰計畫
我們計畫在日後推出的版本中淘汰 usesCleartextTraffic 元素。
如果應用程式需要建立未加密 (HTTP) 連線,請改用網路安全性設定檔,指定應用程式需要建立明文連線的網域。
請注意,網路安全性設定檔僅適用於 API 級別 24 以上版本。如果應用程式的最低 API 級別低於 24,請同時執行下列操作:
- 將
usesCleartextTraffic屬性設為true - 使用網路設定檔
如果應用程式的最低 API 級別為 24 以上,您可以使用網路設定檔,不必設定 usesCleartextTraffic。
限制隱含 URI 授權
目前,如果應用程式啟動的意圖含有 URI,且該 URI 的動作為 ACTION_SEND、SEND_MULTIPLE 或 ACTION_IMAGE_CAPTURE,系統會自動授予目標應用程式讀取和寫入 URI 的權限。我們計畫在 Android 18 中變更這項行為。因此,建議應用程式明確授予相關 URI 權限,而非依賴系統授予權限。
每個應用程式的 Keystore 限制
應用程式應避免在 Android Keystore 中建立過多金鑰,因為這是裝置上所有應用程式共用的資源。從 Android 17 開始,系統會強制限制應用程式可擁有的金鑰數量。如果非系統應用程式指定 Android 17 (API 級別 37) 以上版本,金鑰上限為 50,000 個;其他應用程式的金鑰上限則為 200,000 個。無論目標 API 級別為何,系統應用程式最多只能有 200,000 個金鑰。
如果應用程式嘗試建立超出上限的金鑰,系統會傳回 KeyStoreException,導致建立作業失敗。例外狀況的訊息字串包含金鑰限制的相關資訊。如果應用程式在例外狀況中呼叫 getNumericErrorCode(),傳回值會因應用程式的目標 API 級別而異:
- 以 Android 17 (API 級別 37) 以上版本為目標的應用程式:
getNumericErrorCode()會傳回新的ERROR_TOO_MANY_KEYS值。 - 所有其他應用程式:
getNumericErrorCode()退貨ERROR_INCORRECT_USAGE。
封鎖跨設定檔迴路流量
從 Android 17 開始,系統預設不再允許跨設定檔迴路流量。同一設定檔內的迴路流量不受影響。無論應用程式指定哪個 API 級別,只要在 Android 17 以上版本上執行,都會受到這項變更影響。
使用者體驗和系統 UI
Android 17 包含下列變更,目的是為了打造更一致、直覺的使用者體驗。
裝置旋轉後自動恢復預設的 IME 版面空間
从 Android 17 开始,当设备的配置发生变化(例如,通过旋转)且应用本身未处理此变化时,系统不会恢复之前的 IME 可见性。
如果应用经历了它无法处理的配置更改,并且应用需要在更改后显示键盘,您必须明确请求此行为。您可以通过以下方式之一提出此要求:
- 将
android:windowSoftInputMode属性设置为stateAlwaysVisible。 - 在 activity 的
onCreate()方法中以编程方式请求显示软键盘,或添加onConfigurationChanged()方法。
手動輸入
Android 17 包含下列異動項目,這些變更會影響應用程式與鍵盤和觸控板等人工輸入裝置的互動方式。
在指標擷取期間,觸控板預設會傳送相對事件
从 Android 17 开始,如果应用使用 View.requestPointerCapture() 请求捕获指针,并且用户使用触控板,系统会识别用户触摸操作产生的指针移动和滚动手势,并以与捕获的鼠标产生的指针和滚轮移动相同的方式将这些信息报告给应用。在大多数情况下,这使得支持捕获鼠标的应用无需为触控板添加特殊的处理逻辑。如需了解详情,请参阅 View.POINTER_CAPTURE_MODE_RELATIVE 的文档。
之前,系统不会尝试识别触控板的手势,而是以类似于触摸屏触摸的格式将原始的绝对手指位置传递给应用。如果应用仍需要此绝对数据,则应改为使用 View.POINTER_CAPTURE_MODE_ABSOLUTE 调用新的 View.requestPointerCapture(int) 方法。
媒體
Android 17 包含下列媒體行為變更。
背景音訊強化
從 Android 17 開始,音訊架構會強制限制背景音訊互動,包括音訊播放、音訊焦點要求和音量變更 API,確保這些變更是由使用者刻意啟動。
如果應用程式嘗試在無效的生命週期呼叫音訊 API,音訊播放和音量變更 API 會無聲無息地失敗,不會擲回例外狀況或提供失敗訊息。音訊焦點 API 失敗,結果代碼為 AUDIOFOCUS_REQUEST_FAILED。
如需更多資訊 (包括緩解策略),請參閱「背景音訊強化」。
連線能力
Android 17 包含下列異動項目,可提升裝置連線能力。
藍牙配對遺失時自動重新配對
Android 17 引入了自主重新配对功能,这是一项系统级增强功能,旨在自动解决蓝牙配对信息丢失问题。
以前,如果配对信息丢失,用户必须手动前往“设置”取消配对,然后重新配对外围设备。此功能以 Android 16 的安全改进为基础,允许系统在后台重新建立配对信息,而无需用户手动前往“设置”取消配对并重新配对外围设备。
虽然大多数应用不需要更改代码,但开发者应注意蓝牙堆栈中的以下行为变更:
- 新的配对上下文:
ACTION_PAIRING_REQUEST现在包含EXTRA_PAIRING_CONTEXTextra,允许应用区分 标准配对请求和自主系统发起的重新配对尝试。 - 有条件的密钥更新:只有在重新配对成功且新连接达到或超过之前配对信息的安全级别时,才会替换现有安全密钥。
- 修改后的 intent 时间:现在,只有在自主重新配对尝试失败时,才会广播
ACTION_KEY_MISSINGintent。如果系统在后台成功恢复配对信息,则可以减少应用中不必要的错误处理。 - 用户通知:系统通过新的界面通知和对话框管理重新配对。系统会提示用户确认重新配对尝试,以确保用户了解重新连接。
外围设备制造商和配套应用开发者应验证硬件和应用是否能妥善处理配对信息转换。如需测试此行为,请使用以下任一方法模拟远程配对信息丢失:
- 从外围设备中手动移除配对信息
- 在“设置”>“已连接的设备”中手动取消配对设备