行為變更:所有應用程式

Android 10 包含可能影響應用程式的行為變更。 此頁面列出的變更會套用至您的應用程式執行時 在 Android 10 上執行,無論應用程式的 targetSdkVersion 為何。建議您測試 並視需要進行修改,以便妥善支援這些變更。

如果應用程式的 targetSdkVersion 為 29 以上版本,您也需要 支援進一步變更請務必詳閱應用程式的行為變更 指定 29 來瞭解詳情。

注意:除了本頁所列的變更項目外,Android 10 還推出了許多以隱私權為基礎的變更和限制,包括:

  • 裝置位置資訊的背景存取權
  • 背景活動開始
  • 聯絡人相依性資訊
  • MAC 位址隨機化
  • 相機中繼資料
  • 權限模型

這些變更會影響所有應用程式,並強化使用者隱私權。如要進一步瞭解 如何支援這些變更,請參閱 隱私權變更網頁。

非 SDK 介面限制

為確保應用程式的穩定性和相容性,平台已開始限制應用程式 哪些非 SDK 介面 應用程式可在 Android 9 (API 級別 28) 中使用。基於與 Android 開發人員合作及最新的內部測試,Android 10 包含更新後的受限制非 SDK 介面清單。我們的目標是在限制非 SDK 介面之前,確保公開替代方案的可用性。

如果您不會將 Android 10 (API 級別 29) 設為目標版本,則此處所述的某些變更可能不會立即對您造成影響。不過,雖然您目前可以使用 非 SDK 介面 (視應用程式的目標 API 級別而定), 使用任何非 SDK 方法或欄位,都有很高的風險 應用程式。

如果不確定應用程式是否使用非 SDK 介面,您可以 測試應用程式 瞭解詳情。如果您的應用程式仰賴非 SDK 介面,則建議您開始規劃 改用 SDK 替代方案我們瞭解有些應用程式 使用非 SDK 介面的有效用途。如果您除了為應用程式中的某個功能使用非 SDK 介面外,已別無他法,則應要求新的公用 API

詳情請參閱 Android 10 的非 SDK 介面限制更新內容 ,請參閱「非 SDK 介面的限制」。

手勢操作

從 Android 10 開始,使用者可以在應用程式中啟用手勢操作, 裝置。如果使用者啟用手勢操作模式,裝置上的所有應用程式都會受到這項設定影響。 裝置。例如,使用者在應用程式中滑動 系統就會將該手勢解讀為返回手勢 瀏覽方式,除非應用程式特別覆寫該手勢, 。

為了讓應用程式與手勢操作相容,建議你擴充 邊緣到邊緣的應用程式內容,並妥善處理衝突的手勢。 詳情請參閱手勢操作 說明文件。

NDK

Android 10 包含下列 NDK 異動。

共用物件不得包含文字再定位

Android 6.0 (API 級別 23) 不允許使用 共用物件內的文字再定位程式碼必須維持原樣載入,且不得修改。這項變更可以改善應用程式載入時間和安全性。

SELinux 會對指定 Android 10 為目標版本的應用程式強制執行這項限制 或更高版本。如果這些應用程式繼續使用含有文字的共用物件 而重新定位時,這些物件很有破壞性的風險。

Bionic 程式庫和動態連結器路徑異動

從 Android 10 開始,多條路徑為符號連結,而非 一般檔案。一直仰賴一般檔案路徑的應用程式 可能會損毀:

  • /system/lib/libc.so -> /apex/com.android.runtime/lib/bionic/libc.so
  • /system/lib/libm.so -> /apex/com.android.runtime/lib/bionic/libm.so
  • /system/lib/libdl.so -> /apex/com.android.runtime/lib/bionic/libdl.so
  • /system/bin/linker -> /apex/com.android.runtime/bin/linker

這些變更也適用於檔案的 64 位元變化版本, 以「lib64/」取代「lib/」。

為了相容性,您可以在舊路徑中提供符號連結。例如: /system/lib/libc.so 是以下項目的符號連結: /apex/com.android.runtime/lib/bionic/libc.so。以下內容 「dlopen(“/system/lib/libc.so”)」會繼續運作,但應用程式會找到 瞭解他們實際嘗試檢查載入程式庫時的差異 /proc/self/maps或類似功能,但我們發現實際上 有些應用程式會將這種情況做防駭客入侵程序。如果是的話, /apex/… 路徑應新增為 Bionic 檔案的有效路徑。

對應至僅限執行記憶體的系統二進位檔/程式庫

自 Android 10 起,系統二進位檔和程式庫的可執行部分會對應至記憶體執行 (不可讀取),做為防範程式碼重用攻擊的強化技術。如果您的應用程式執行讀取作業,且記憶體區段標示為僅執行 (無論是因為錯誤、安全漏洞或有意記憶體檢查),系統就會向應用程式傳送 SIGSEGV 信號。

你可以查看 /data/tombstones/ 中的 Tombstone 檔案。僅與執行相關的當機事件 包含下列取消訊息:

Cause: execute-only (no-read) memory access error; likely due to data in .text.

如要解決這個問題 以便執行記憶體檢查等作業 ,透過呼叫 mprotect()。不過我們強烈建議您將設定改回 因為這項存取權限設定能 保護應用程式和使用者

安全性

Android 10 提供下列安全性變更。

預設啟用 TLS 1.3

在 Android 10 以上版本中,系統預設會啟用 TLS 1.3 傳輸層安全標準 (TLS) 連線。以下是有關傳輸層安全標準 (TLS) 1.3 的幾項重要細節 實作:

  • TLS 1.3 加密套件不開放自訂。支援的 TLS 1.3 加密方式 啟用 TLS 1.3 時,一律會啟用套件。任何嘗試停用 呼叫 setEnabledCipherSuites()敬上 系統就會忽略。
  • 交涉 TLS 1.3 時 HandshakeCompletedListener敬上 則要先呼叫物件,再將工作階段加入工作階段快取。(在 TLS 1.2 中) 和其他舊版本都會呼叫這些物件,在新增工作階段「之後」 傳送至工作階段快取)。
  • 在某些情況下,如果 SSLEngine 例項在舊版 Android 上擲回 SSLHandshakeException,這些例項會在 Android 10 以上版本擲回 SSLProtocolException
  • 不支援 0-RTT 模式。

如有需要,您可以呼叫SSLContext SSLContext.getInstance("TLSv1.2")。 您也可以對適當物件呼叫 setEnabledProtocols(),根據個別連線啟用或停用通訊協定版本。

使用 SHA-1 簽署的憑證不受 TLS 信任

在 Android 10 中,憑證採用 SHA-1 雜湊演算法 不受 TLS 連線信任的憑證。根 CA 尚未核發這類憑證 ,Chrome 或其他主要瀏覽器已經不再信任這類瀏覽器。

如果連線目標為出現 憑證

KeyChain 行為變更和強化措施

某些瀏覽器 (例如 Google Chrome) 會在 TLS 伺服器會在 TLS 握手期間傳送憑證要求訊息。在 Android 10,KeyChain 物件會在呼叫 KeyChain.choosePrivateKeyAlias() 來向使用者顯示憑證選擇提示時,遵循頒發單位和金鑰規格參數。具體來說,此提示含有的選項皆符合伺服器規格。

如果沒有可供使用者選取的憑證,就像沒有使用者可選取的憑證一樣 憑證符合伺服器規格,或裝置中沒有任何憑證 憑證選取提示後,系統完全不會顯示憑證選取提示。

此外,Android 10 以上版本不必具備 裝置螢幕鎖定,即可將金鑰或 CA 憑證匯入 KeyChain 物件。

其他 TLS 和密碼學變更

TLS 和密碼學程式庫有幾項小幅變更 適用於 Android 10 版本:

  • AES/GCM/NoPadding 和 ChaCha20/Poly1305/NoPadding 加密會傳回更多 從 getOutputSize() 取得正確的緩衝區空間
  • 系統會在下列嘗試連線時省略 TLS_FALLBACK_SCSV 加密套件: 傳輸層安全標準 (TLS) 1.2 以上版本的最大通訊協定。TLS 伺服器經過改善 實作,建議您不要嘗試採用 TLS 外部備用機制。 就建議採用 TLS 版本協商
  • ChaCha20-Poly1305 是 ChaCha20/Poly1305/NoPadding 的別名。
  • 以點結尾的主機名稱並非有效的 SNI 主機名稱。
  • CertificateRequest 中的 supported_signature_algorithms 擴充功能為 選擇憑證回應的簽署金鑰時,應遵守這個值。
  • 在 TLS 中,Android KeyStore 金鑰等不透明的簽署金鑰可以與 RSA-PSS 簽署搭配使用。

Wi-Fi Direct 廣播

在 Android 10 中,下列與 Wi-Fi 相關的廣播訊息 直接不固定:

如果您的應用程式在註冊時需要接收這些廣播訊息, 而是在初始化時使用適當的 get() 方法, 取得相關資訊

Wi-Fi 感知功能

Android 10 開始支援透過 Wi-Fi Aware 建立 TCP/UDP 通訊端 資料路徑如要建立連線至 ServerSocket 的 TCP/UDP 通訊端, 裝置都必須知道伺服器的 IPv6 位址和通訊埠。先前 必須透過頻外通訊,例如使用 BT 或 Wi-Fi 感知層 2 訊息,或是在 mDNS 等其他通訊協定中發現。取代為 Android 10 時,可在設定過程中傳遞相關資訊。

伺服器可以執行下列其中一項操作:

  • 初始化 ServerSocket,並設定或取得要使用的通訊埠。
  • 在 Wi-Fi Aware 網路要求中指定通訊埠資訊。

以下程式碼範例顯示如何將通訊埠資訊在 網路要求:

Kotlin

val ss = ServerSocket()
val ns = WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle)
  .setPskPassphrase("some-password")
  .setPort(ss.localPort)
  .build()

val myNetworkRequest = NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
  .setNetworkSpecifier(ns)
  .build()

Java

ServerSocket ss = new ServerSocket();
WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier
  .Builder(discoverySession, peerHandle)
  .setPskPassphrase(some-password)
  .setPort(ss.getLocalPort())
  .build();

NetworkRequest myNetworkRequest = new NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
  .setNetworkSpecifier(ns)
  .build();

接著,用戶端會執行 Wi-Fi Aware 網路要求來取得 IPv6 伺服器提供的通訊埠:

Kotlin

val callback = object : ConnectivityManager.NetworkCallback() {
  override fun onAvailable(network: Network) {
    ...
  }
  
  override fun onLinkPropertiesChanged(network: Network,
      linkProperties: LinkProperties) {
    ...
  }

  override fun onCapabilitiesChanged(network: Network,
      networkCapabilities: NetworkCapabilities) {
    ...
    val ti = networkCapabilities.transportInfo
    if (ti is WifiAwareNetworkInfo) {
       val peerAddress = ti.peerIpv6Addr
       val peerPort = ti.port
    }
  }
  override fun onLost(network: Network) {
    ...
  }
};

connMgr.requestNetwork(networkRequest, callback)

Java

callback = new ConnectivityManager.NetworkCallback() {
  @Override
  public void onAvailable(Network network) {
    ...
  }
  @Override
  public void onLinkPropertiesChanged(Network network,
      LinkProperties linkProperties) {
    ...
  }
  @Override
  public void onCapabilitiesChanged(Network network,
      NetworkCapabilities networkCapabilities) {
    ...
    TransportInfo ti = networkCapabilities.getTransportInfo();
    if (ti instanceof WifiAwareNetworkInfo) {
       WifiAwareNetworkInfo info = (WifiAwareNetworkInfo) ti;
       Inet6Address peerAddress = info.getPeerIpv6Addr();
       int peerPort = info.getPort();
    }
  }
  @Override
  public void onLost(Network network) {
    ...
  }
};

connMgr.requestNetwork(networkRequest, callback);

Go 裝置上的 SYSTEM_ALERT_WINDOW

在 Android 10 (Go 版本) 裝置上執行的應用程式無法接收 SYSTEM_ALERT_WINDOW敬上 權限。這是因為繪製重疊視窗使用過多記憶體 這對記憶體不足的 Android 效能特別造成負面影響 裝置。

如果在搭載 Android 9 以下版本的 Go 版裝置上執行的應用程式收到 SYSTEM_ALERT_WINDOW 權限,即使裝置升級至 Android 10,應用程式仍會保留該權限。不過,目前還沒有 裝置升級後便無法授予此權限。

如果 Go 裝置上的應用程式傳送含有動作的意圖 ACTION_MANAGE_OVERLAY_PERMISSION、 系統會自動拒絕要求,並將使用者導向 「設定」畫面,顯示該權限不允許使用 會讓裝置執行速度變慢。如果在 Go 裝置上呼叫應用程式 Settings.canDrawOverlays()、 此方法一律傳回 false再次強調,這些限制不適用於應用程式 在裝置開始前收到SYSTEM_ALERT_WINDOW權限 已升級至 Android 10

應用程式指定舊版 Android 裝置的警告

搭載 Android 10 以上版本的裝置首次警告使用者 並執行指定 Android 5.1 (API 級別 22) 以下版本的應用程式。如果應用程式需要使用者授予權限,在允許應用程式首次執行前,使用者也有機會調整應用程式的權限。

由於 Google Play 的目標 API API 設定 相關規定 使用者只有在執行未經更新的應用程式時,系統才會顯示這些警告 。如果是透過其他商店發行的應用程式,類似的目標 API 需求從 2019 年開始生效。如要進一步瞭解這些 相關規定,請參閱如何擴大目標 API 級別規定: 2019 年

已移除 SHA-2 CBC 加密套件

下列 SHA-2 CBC 加密組合已從平台中移除:

  • TLS_RSA_WITH_AES_128_CBC_SHA256
  • TLS_RSA_WITH_AES_256_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384

相較於使用 GCM 的類似加密套件,這些加密套件的安全性較低 而大多數伺服器都同時支援這些加密的 GCM 和 CBC 變化版本 兩者都不得配置

應用程式使用情況

Android 10 推出了下列與應用程式使用情形相關的行為變更:

  • UsageStats 應用程式用量改善功能 - 在應用程式以分割畫面或子母畫面模式使用時,Android 10 會使用 UsageStats 準確追蹤應用程式用量。此外, Android 10 可正確追蹤免安裝應用程式的使用情形。

  • 個別應用程式灰階 -

  • 個別應用程式乾擾狀態 - Android 10 可以選擇性地將應用程式設為「抽象狀態」在哪? 系統不會顯示通知,也不會顯示為建議的應用程式。

  • 停權與播放 - 在 Android 10 中,已暫停的應用程式無法播放音訊。

HTTPS 連線變更

如果執行 Android 10 的應用程式將 null 傳遞至 setSSLSocketFactory(),就會發生 IllegalArgumentException。在先前版本中,將 null 傳遞至 setSSLSocketFactory() 效果與傳入目前預設 工廠

android.preference 程式庫已淘汰

android.preference 程式庫已於 Android 10 淘汰。 開發人員應改用 AndroidX 偏好設定資料庫,這是 Android 的一部分 Jetpack。如需協助遷移和 請參閱新版設定 指南和我們的公開樣本 應用程式 以及參考說明文件

ZIP 檔案公用程式庫異動

Android 10 推出了下列 java.util.zip 類別異動 套件,負責處理 ZIP 檔案。這些變更可讓 Android 和使用 java.util.zip 的其他平台之間的程式庫行為更一致。

發射機

在先前的版本中,Inflater 類別中的部分方法擲回 IllegalStateException 表示 是在呼叫 end() 後叫用。 在 Android 10 中,這些方法會擲回 NullPointerException

ZipFile

在 Android 10 以上版本中, ZipFile 取用 FileintCharset 類型的引數時,不會擲回 如果提供的 ZIP 檔案是由 ZipException 提供, 不含任何檔案

ZipOutputStream

在 Android 10 以上版本中, finish() 方法 ZipOutputStream 不會擲回 如果它嘗試寫入,則為 ZipException 輸出內容串流。

相機變更

許多使用相機的應用程式都會假設,如果裝置處於直向設定,實體裝置也處於直向,如「相機方向」一文所述。這是過去的安全假設,但 隨著各種板型規格 (例如折疊式裝置) 的擴展而發生了變化。沒錯 這可能導致裝置旋轉或縮放倍率 (或 兩個) 相機觀景窗的畫面。

目標 API 級別 24 以上的應用程式應明確設定 請android:resizeableActivity,並提供處理必要功能 執行多視窗作業

電池用量追蹤

從 Android 10 開始 已重設 SystemHealthManager 裝置在完成電源後拔掉時,電池用量統計資料 。一般來說,主要充電事件是指裝置已充飽電,或裝置從幾乎沒電到幾乎充飽電。

在 Android 10 之前,無論電池電量有多少變化,只要拔除裝置插頭,電池用量統計資料就會重設。

Android Beam 淘汰

在 Android 10 中,我們正式淘汰 Android Beam 這項舊版功能: 透過近距離無線通訊 (NFC) 啟動不同裝置的資料分享作業。 我們也將淘汰多個相關的 NFC API。Android Beam 剩餘 可以選擇提供給需要,但實際上 也更久Android 會繼續支援其他 NFC 功能和 API,以及從標記和 API 讀取等用途 付款仍將照常運作。

java.math.BigDecimal.stripTrailingZeros() 行為變更

BigDecimal.stripTrailingZeros() 不再以零做為結尾 ( 特殊情況。

java.util.regex.Matcher 和模式行為變更

split() 的結果已變更為不再以空白的 String 開頭 (「」) 表示。這也 影響:String.split()。例如,"x".split("") 現在會傳回 {"x"} 在舊版 Android 上則用於傳回 {"", "x"}"aardvark".split("(?=a)" 現在會傳回 {"a", "ardv", "ark"},而非 {"", "a", "ardv", "ark"}

我們也改善了無效引數的例外狀況行為:

  • 如果替換的 String 結尾為非法的單一反斜線,appendReplacement(StringBuffer, String) 現在會擲回 IllegalArgumentException,而非 IndexOutOfBoundsException。 如果替換的 String$ 結尾,系統會擲回相同的例外狀況。 先前在這個情況下不會擲回例外狀況。
  • 如果擲回 replaceFirst(null),則 replaceFirst(null) 不會再對 Matcher 呼叫 reset() NullPointerException。現在也會擲回 NullPointerException 沒有符合項目。以往,只有在配對成功時才會擲回。
  • 如果群組索引超出範圍,start(int group)end(int group)group(int group) 現在會擲回較通用的 IndexOutOfBoundsException。先前,這些方法會擲回 ArrayIndexOutOfBoundsException

GradientDrawable 的預設角度現在是 TOP_BOTTOM

在 Android 10 中,如果您定義了 GradientDrawable敬上 在 XML 中,且未提供角度測量值、漸層方向 預設為 TOP_BOTTOM。 這是與舊版 Android 相比的變化,預設版本為 LEFT_RIGHT

如要解決這個問題,如果更新至最新版 AAPT2, 如果沒有角度,這項工具會為舊版應用程式設定 0 的角度測量結果 。

使用預設 SUID 的序列化物件記錄功能

從 Android 7.0 (API 級別 24) 開始,平台會進行修正 設為可序列化的預設 serialVersionUID 這項修正 不會影響目標 API 級別 23 以下的應用程式。

從 Android 10 開始,如果應用程式指定 API 級別 23 以下, 並仰賴舊、錯誤、預設 serialVersionUID、系統記錄 並說明程式碼修正建議

具體來說,如果符合下列所有條件,系統就會記錄警告:

  • 應用程式指定 API 級別 23 以下為目標。
  • 類別已序列化。
  • 序列化類別會使用預設的 serialVersionUID,而非 明確設定 serialVersionUID
  • 預設的 serialVersionUIDserialVersionUID 不同 前提是應用程式指定的 API 級別為 24 以上。

系統會針對每個受影響的課程記錄一次這項警告。 警告訊息含有修正建議,也就是必須明確設定的 serialVersionUID 改為計算預設值, 應用程式的目標 API 級別為 24 以上。使用此修正可以確保 如果該類別的物件在目標 API 級別的應用程式上序列化 23 以下版本,目標 24 以上的應用程式就能正確讀取物件 反之亦然

java.io.FileChannel.map() 變更

自 Android 10 起,FileChannel.map() 不支援非標準檔案 (例如 /dev/zero),因為無法使用 truncate() 變更其大小。上一題 Android 版本均記錄了 truncate(),但 Android 10 會擲回 IOException。如果您需要舊行為 您必須使用原生程式碼