除了新功能以外,Android 6.0 (API 級別 23) 還包含各種系統變更和 API 行為變更。本文件重點介紹應用程式中應瞭解和考量的一些重要異動。
如果您先前已發布 Android 應用程式,請注意平台上的這些變更會影響您的應用程式。
執行階段權限
這個版本推出全新的權限模型,讓使用者能夠在執行階段直接管理應用程式權限。這個模型可讓使用者進一步掌握及控管權限,同時簡化應用程式開發人員的安裝和自動更新程序。使用者可以針對已安裝的應用程式個別授予或撤銷權限。
針對指定 Android 6.0 (API 級別 23) 以上版本的應用程式,請務必在執行階段檢查及要求權限。如要判斷應用程式是否已獲得權限,請呼叫新的 checkSelfPermission()
方法。如要要求權限,請呼叫新的 requestPermissions()
方法。即使應用程式未指定 Android 6.0 (API 級別 23),您仍然應使用新的權限模型測試應用程式。
如要進一步瞭解如何在應用程式中支援新權限模型,請參閱 使用系統權限一文。如需瞭解如何評估應用程式影響的提示,請參閱「權限使用注意事項」。
打盹和應用程式待命
這個版本針對閒置裝置和應用程式推出新的省電最佳化功能。這些功能會影響所有應用程式,因此請務必在這些新模式中測試您的應用程式。
- 打盹:如果使用者拔除裝置電源後未離開螢幕,並在螢幕關閉一段時間內關閉,裝置會進入「打盹」模式,嘗試讓系統保持在休眠狀態。在這個模式下,裝置會定期恢復正常作業,以便系統同步處理應用程式,並讓系統執行任何待處理作業。
- 應用程式待命:應用程式待命功能可讓系統在使用者未主動使用應用程式時,判斷應用程式是否處於閒置狀態。當使用者在特定時間內未輕觸應用程式時,系統會做出判斷。如果裝置未接上電源,系統會停用網路存取權,並針對閒置狀態的應用程式暫停同步處理和工作。
如要進一步瞭解這些省電變更,請參閱針對打盹和應用程式待命進行最佳化。
移除 Apache HTTP 用戶端
Android 6.0 版本移除了對 Apache HTTP 用戶端的支援。如果您的應用程式使用這個用戶端,而且指定 Android 2.3 (API 級別 9) 以上版本,請改用 HttpURLConnection
類別。這個 API 的效率較高,因為此 API 會透過透明的壓縮和回應快取功能減少網路用量,並將耗電量降到最低。如要繼續使用 Apache HTTP API,您必須先在 build.gradle
檔案中宣告下列編譯時間依附元件:
android { useLibrary 'org.apache.http.legacy' }
BoringSSL
Android 即將從 OpenSSL 移至 BoringSSL 程式庫。如果您在應用程式中使用 Android NDK,請勿連結至不屬於 NDK API 的加密編譯程式庫,例如 libcrypto.so
和 libssl.so
。這些程式庫並非公開 API,且可能會在未事先通知的情況下變更或中斷。此外,您也可能會面臨安全漏洞。請改為修改原生程式碼,透過 JNI 呼叫 Java 密碼編譯 API,或是以靜態方式連結至所選密碼編譯程式庫。
硬體 ID 存取權
為提供使用者更完善的資料保護,從這個版本開始,針對使用 Wi-Fi 和 Bluetooth API 的應用程式,Android 會移除其裝置本機硬體 ID 的程式輔助存取權。WifiInfo.getMacAddress()
和 BluetoothAdapter.getAddress()
方法現在會傳回常數值 02:00:00:00:00:00
。
如要透過藍牙和 Wi-Fi 掃描功能存取附近裝置的硬體 ID,您的應用程式現在必須具有 ACCESS_FINE_LOCATION
或 ACCESS_COARSE_LOCATION
權限:
注意:當搭載 Android 6.0 (API 級別 23) 的裝置啟動背景 Wi-Fi 或藍牙掃描時,外部裝置會看到作業來自隨機 MAC 位址。
通知
這個版本會移除 Notification.setLatestEventInfo()
方法。請改用 Notification.Builder
類別建構通知。如要重複更新通知,請重複使用 Notification.Builder
執行個體。呼叫 build()
方法,取得更新的 Notification
執行個體。
adb shell dumpsys notification
指令不會再輸出通知文字。請改用 adb shell dumpsys notification --noredact
指令輸出通知物件中的文字。
AudioManager 變更
系統不再支援透過 AudioManager
類別直接設定音量,或忽略特定串流。setStreamSolo()
方法已淘汰,應改為呼叫 requestAudioFocus()
方法。同樣地,setStreamMute()
方法也已淘汰;請改為呼叫 adjustStreamVolume()
方法,並傳遞方向值 ADJUST_MUTE
或 ADJUST_UNMUTE
。
文字選取
![畫面在浮動工具列中顯示新的文字選取功能](https://developer.android.google.cn/static/images/android-6.0/text-selection.gif?authuser=3&hl=zh-tw)
使用者在應用程式中選取文字時,您現在可以在浮動式工具列中顯示文字選取動作,例如「Cut」、「Copy」和「Paste」。使用者互動實作方式與關聯動作列類似,請參閱 為個別檢視畫面啟用關聯動作模式一文。
如要實作浮動式工具列以進行文字選取,請在現有應用程式中進行下列變更:
- 在
View
或Activity
物件中,將ActionMode
呼叫從startActionMode(Callback)
變更為startActionMode(Callback, ActionMode.TYPE_FLOATING)
。 - 使用現有的
ActionMode.Callback
實作,並改為擴充ActionMode.Callback2
。 - 覆寫
onGetContentRect()
方法,以提供檢視畫面中內容Rect
物件的座標 (例如文字選取矩形)。 - 如果矩形位置已失效,且這是唯一要失效的元素,請呼叫
invalidateContentRect()
方法。
如果您使用
Android 支援資料庫修訂版本 22.2,請注意浮動工具列無法回溯相容,而且根據預設,appcompat 會控管 ActionMode
物件。這麼做可避免浮動工具列顯示。如要在 AppCompatActivity
中啟用 ActionMode
支援,請呼叫 getDelegate()
,然後在傳回的 AppCompatDelegate
物件上呼叫 setHandleNativeActionModesEnabled()
,並將輸入參數設為 false
。這項呼叫會將 ActionMode
物件的控制權傳回架構。在搭載 Android 6.0 (API 級別 23) 的裝置上,允許架構支援 ActionBar
或浮動工具列模式;在搭載 Android 5.1 (API 級別 22) 以下版本的裝置上,僅支援 ActionBar
模式。
瀏覽器書籤變更
這個版本不再支援全域書籤。現已移除 android.provider.Browser.getAllBookmarks()
和 android.provider.Browser.saveBookmark()
方法。同樣地,READ_HISTORY_BOOKMARKS
和 WRITE_HISTORY_BOOKMARKS
權限也會移除。如果您的應用程式指定 Android 6.0 (API 級別 23) 以上版本,請勿存取全域提供者的書籤,或使用書籤權限。應用程式應改為將書籤資料儲存在內部。
Android KeyStore 變更
這個版本推出後,Android KeyStore 供應器將不再支援 DSA。但系統仍支援 ECDSA。
使用者或裝置管理員等安全螢幕鎖定停用或重設時,不需要靜態加密的金鑰將不再遭到刪除。需要靜態加密的金鑰會在這些事件期間刪除。
Wi-Fi 和網路變更
此版本導入 Wi-Fi 和網路 API 的行為變更。
- 現在,只有在您建立這些物件的情況下,應用程式才能變更
WifiConfiguration
物件的狀態。您不得修改或刪除使用者或其他應用程式建立的WifiConfiguration
物件。 -
以前,如果應用程式透過
disableAllOthers=true
設定使用enableNetwork()
強制裝置連線至特定 Wi-Fi 網路,則裝置會與行動數據等其他網路中斷連線。在此版本中,裝置不再與其他網路中斷連線。如果應用程式的targetSdkVersion
為“20”
以下,則會固定在所選的 Wi-Fi 網路。如果應用程式的targetSdkVersion
為“21”
以上版本,請使用多網路 API (例如openConnection()
、bindSocket()
和新的bindProcessToNetwork()
方法),確保其網路流量傳送至所選網路。
相機服務變更
在這個版本中,用於在相機服務中存取共用資源的模型已從先前的「先進先進」存取模型,變更為優先處理高優先順序程序的存取模型。服務行為的變更包括:
- 相機子系統資源 (包括開啟和設定相機裝置) 的存取權取決於用戶端應用程式程序的「優先順序」。具有使用者可見或前景活動的應用程式程序通常優先順序較高,使得相機資源獲取和使用更加可靠。
- 當優先順序較高的應用程式嘗試使用相機時,系統可能會「撤銷」優先順序較低的應用程式使用中的相機用戶端。在已淘汰的
Camera
API 中,這會導致系統針對已撤銷的用戶端呼叫onError()
。在Camera2
API 中,系統會針對已撤銷的用戶端呼叫onDisconnected()
。 - 在配備適當的相機硬體裝置中,不同的應用程式程序可同時開啟及使用不同的相機裝置。然而,相機服務會偵測並禁止多程序用途,同時進行存取會導致任何已開啟的相機裝置的效能或功能大幅降低。即使沒有其他應用程式直接嘗試存取同一相機裝置,這項變更仍可能為較低優先順序的用戶端「撤銷」。
- 變更目前的使用者會導致前一個使用者帳戶擁有的應用程式中移除有效的相機用戶端。只有目前裝置使用者擁有的使用者個人資料才能存取攝影機。 實際上,這表示當使用者切換至其他帳戶時,使用相機子系統的執行中程序 (例如「訪客」帳戶) 將無法離開。
執行階段
ART 執行階段現在可正確實作 newInstance()
方法的存取規則。這項變更修正了 Dalvik 在先前版本中無法正確檢查存取規則的問題。如果您的應用程式使用 newInstance()
方法,而且您想覆寫存取權檢查,請呼叫 setAccessible()
方法,並將輸入參數設為 true
。如果應用程式使用 v7 appcompat 程式庫或 v7 Recyclerview 程式庫,您必須將應用程式更新為使用這些程式庫的最新版本。否則,請確認 XML 參照的所有自訂類別皆已更新,以便存取其類別建構函式。
這個版本更新動態連接器的行為。動態連結器現在可瞭解程式庫的 soname
及其路徑 (
公開錯誤 6670) 之間的差異,且現已實作 soname
搜尋功能。如果應用程式之前曾運作過錯誤的 DT_NEEDED
項目 (通常是建構機器檔案系統上的絕對路徑),則可能會在載入時失敗。
dlopen(3) RTLD_LOCAL
旗標現已正確實作。請注意,RTLD_LOCAL
為預設值,因此對未明確使用 RTLD_LOCAL
的 dlopen(3)
呼叫會受到影響 (除非應用程式明確使用 RTLD_GLOBAL
)。如果使用 RTLD_LOCAL
,則後續呼叫 dlopen(3)
所載入的程式庫無法使用符號 (而非由 DT_NEEDED
項目參照),
在舊版 Android 中,如果應用程式要求系統載入含有文字重新定位的共用資料庫,系統會顯示警告,但仍可載入程式庫。從這個版本開始,如果應用程式的目標 SDK 版本為 23 以上,系統會拒絕這個程式庫。為協助您偵測程式庫是否無法載入,應用程式應記錄 dlopen(3)
失敗情形,並納入 dlerror(3)
呼叫傳回的問題說明文字。如要進一步瞭解如何處理文字重新定位,請參閱這份指南。
APK 驗證
平台現在會對 APK 執行更嚴格的驗證。如果資訊清單中宣告檔案,但 APK 並未顯示該檔案,APK 就會視為損毀。如果有任何內容遭到移除,APK 必須重新簽署。
USB 連接
根據預設,透過 USB 連接埠裝置連線的功能已設為僅限充電模式。如要透過 USB 連線存取裝置及其內容,使用者必須明確授予這類互動的權限。如果應用程式支援使用者透過 USB 連接埠與裝置互動,請注意必須明確啟用互動功能。
Android for Work 異動
這個版本包含下列 Android for Work 行為變更:
- 個人工作中的工作聯絡人。使用者查看過往通話時,Google 撥號程式通話記錄現在會顯示工作聯絡人。將
setCrossProfileCallerIdDisabled()
設為true
後,Google 撥號程式通話記錄中就會隱藏工作資料夾聯絡人。只有在setBluetoothContactSharingDisabled()
設為false
的情況下,工作聯絡人才能連同個人聯絡人一起透過藍牙顯示到裝置上。預設值為true
。 - 移除 Wi-Fi 設定:如果工作資料夾遭到刪除,系統會移除設定檔擁有者新增的 Wi-Fi 設定 (例如透過呼叫
addNetwork()
方法)。 - Wi-Fi 設定鎖定:如果
WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN
不是零,使用者就無法再修改或刪除由有效裝置擁有者建立的 Wi-Fi 設定。使用者仍然可以建立及修改自己的 Wi-Fi 設定。使用中的裝置擁有者有權編輯或移除任何 Wi-Fi 設定,包括並非由他們建立的 Wi-Fi 設定。 - 透過新增 Google 帳戶下載裝置政策控制器:如果 Google 帳戶需要透過裝置政策控制器 (DPC) 應用程式進行管理的 Google 帳戶,但加入受管理環境以外的裝置,新增帳戶流程現在會提示使用者安裝適當的 WPC。「設定」>「帳戶」以及初始裝置設定精靈中新增的帳戶也會套用這個行為。
- 特定
DevicePolicyManager
API 行為異動:- 呼叫
setCameraDisabled()
方法只會影響呼叫使用者的相機;從受管理的設定檔呼叫相機,不會影響在主要使用者執行的相機應用程式。 - 此外,設定檔擁有者和裝置擁有者現在可使用
setKeyguardDisabledFeatures()
方法。 - 設定檔擁有者可以設定以下鍵盤鎖限制:
KEYGUARD_DISABLE_TRUST_AGENTS
和KEYGUARD_DISABLE_FINGERPRINT
,這會影響設定檔父項使用者的鍵盤鎖設定。KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS
,只會影響受管理設定檔中應用程式產生的通知。
DevicePolicyManager.createAndInitializeUser()
和DevicePolicyManager.createUser()
方法已淘汰。- 當特定使用者的應用程式於前景時,
setScreenCaptureDisabled()
方法現在也會封鎖輔助結構。 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
現在預設為 SHA-256。系統仍支援 SHA-1 以確保回溯相容性,但日後將會移除。EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM
現在只接受 SHA-256。- 現已移除 Android 6.0 (API 級別 23) 中的 Device Initializer API。
- 已移除
EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS
,因此 NFC 接觸佈建程序無法以程式輔助方式解鎖受恢復原廠設定保護的裝置。 - 您現在可以使用
EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
額外項目,在受管理裝置的 NFC 佈建期間,將資料傳送至裝置擁有者應用程式。 - Android for Work API 已針對 M 執行階段權限進行最佳化,包括工作資料夾、輔助層等。新的
DevicePolicyManager
權限 API 不會影響 M 以下版本的應用程式。 - 當使用者退出透過
ACTION_PROVISION_MANAGED_PROFILE
或ACTION_PROVISION_MANAGED_DEVICE
意圖啟動的設定流程的同步部分時,系統會傳回RESULT_CANCELED
結果代碼。
- 呼叫
- 其他 API 變更:
- 數據用量:
android.app.usage.NetworkUsageStats
類別已重新命名為NetworkStats
。
- 數據用量:
- 通用設定變更:
- 這些設定無法再透過
setGlobalSettings()
調整:BLUETOOTH_ON
DEVELOPMENT_SETTINGS_ENABLED
MODE_RINGER
NETWORK_PREFERENCE
WIFI_ON
- 現在可以透過
setGlobalSettings()
調整這些全域設定:
- 這些設定無法再透過