Android 6.0 新功能及主要 API 變更


伴隨着新的特性和功能, Android 6.0 (API 級別 23)帶來了一系列系統和 API 行為的變更。這篇文章中將介紹一些在應用程序中需要理解和注意的主要變更點。

如果你之前已經發布過 Android 應用程序,要意識到這些變更對應用程序的影響。

運行時權限

這個版本中引入了新的權限模型,現在用戶可以在運行時直接管理應用程序的權限。這個模型基於用戶對權限控制的更多可見性,同時為應用程序的開發者提供更流暢的應用安裝和自動升級。用戶可以為已安裝的每個應用程序獨立的授予或者取消權限。

在運行於目標版本 Android 6.0 (API 級別 23) 及以上的應用程序中,必須在運行時檢查並請求權限。通過新的 checkSelfPermission() 方法來確定你的應用程序是否已經被授權。通過新的 requestPermissions() 方法來請求權限。即使你的應用程序運行的目標版本不是 Android 6.0 (API 級別 23),你也應該在新的授權模型下來測試應用程序。

在應用程序中支持新的權限模型的更多詳細信息,可以查看使用系統權限。如何在應用程序中使用權限,相關提示可以查看權限最佳實踐

休眠與應用掛起( Doze and App Standby )

這個版本為空閑的設備和應用程序引入了電源節能優化。這個特性將影響所有應用程序,故確保自己的應用程序在這些新模式下進行測試。

  • 休眠:如果用戶將設備拔下,並將其靜置,關閉屏幕,經過一段時間,設備將進入休眠模式。這時候,設備試圖讓系統保持在一個睡眠的狀態。這種模式下,設備周期性的恢復平常的操作,以便應用程序同步,系統則可以處理一些延時的操作。

  • 應用掛起:應用掛起則允許系統當用戶不再使用應用程序時,將其定義為空閑。當用戶經過一段時間沒有觸摸應用程序時,系統可以做這個決定。設備被拔線時,系統禁用網絡訪問,停止應用程序的同步及操作,則被認為是空閑。

學習更多關於電源節能的變更,查看對休眠與應用掛起的優化

移除 Apache HTTP 客戶端

Android 6.0 發布版移除了對 Apache HTTP 客戶端的支持。如果你的應用程序使用該客戶端,並且目標運行版本為 Android 2.3 (API 級別9) 及以上,需要使用 HttpURLConnection 類來代替。這個 API 更加的高效,因為它通過對用戶透明的壓縮、響應緩存來減少網絡開銷,並最小化電量消耗。要繼續使用 Apache HTTP 的 API,你需要在 build.gradle 文件中聲明下面的編譯期依賴:

1
2
3
android {
useLibrary 'org.apache.http.legacy'
}

BoringSSL

Android 從 OpenSSL 轉移到了 BoringSSL 庫。如果你在應用程序中使用 Android NDK,千萬不要將加密庫鏈接到除 NDK API 之外的任何庫,如 libcrypto.so 和 libssl.so。這些庫不是公開 API,有可能在沒有收到通知的情況下在發布版和設備間發生變更或中斷。這種情況你將把自己暴露在安全威脅下。你應該修改自己的本地代碼來通過 JNI 調用 Java 加密 API 或者靜態鏈接你選擇的一個加密庫。

訪問硬件標識符

為了給用戶更多的數據保護,從這個版本開始, Android 移除了通過 WiFi 和藍牙 API 來在應用程序中可編程的訪問本地硬件標示符。現在 WifiInfo.getMacAddress() 和BluetoothAdapter.getAddress() 方法都將返回 02:00:00:00:00:00 常量。

要通過藍牙和 WiFi 掃描來訪問附近外部設備的硬件標示符,應用程序需要ACCESS_FINE_LOCATION 和 ACCESS_COARSE_LOCATION 權限:

注意:在一個運行 Android 6.0 (API 級別 23) 的設備初始化后台的 WiFi 或藍牙掃描時,操作對於外部設備是可見的,且被賦予一個隨機的 MAC 地址。

通知

這個版本移除了 Notification.setLatestEventInfo() 方法。使用 Notification.Builder 類來代替構造方法。要重復的更新通知,要重用 Notification.Builder 實例。調用 build() 方法來獲取更新過的 Notification 實例。

adb shell dumpsys nnotification 命令不在答應通知文本。使用 adb shell dumpsys notification --noredcat 命令來在同志對象中打印文本。

AudioManager 變更

通過 AudioManager 類來直接設置音量或者使流靜音已經不再支持。 setStreamSolo() 方法被棄用,你需要調用 requestAudioFocus() 來代替。類似的, setStreamMute() 方法被棄用,替換為 adjustStreamVolume() 方法並傳遞方向值 ADJUST_MUTE 或 ADJUST_UNMUTE。

文本選擇

當用戶在應用程序中選擇文本時,你可以在懸浮工具欄中顯示文本選擇工作,如剪切、復制、粘貼。用戶交互實現與為獨立視圖啟動上下文動作模式中描述的上下文動作欄類似。

為文本選擇實現懸浮工具欄,需要在已存在的應用程序中做如下修改:

  1. 在 View 或者 Activity 對象中,通過修改 startActionMode(Callback) 為startActionMode(Callback, ActionMode.TYPE_FLOATING) 來改變 ActionMode。

  2. 使已經存在的 ActionMode.Callback 的實現繼承自 ActionMode.Callback2 。

  3. 重載 onGetContentRect() 方法來提供內容 Rect 對象(如文本選擇矩形)在視圖中的坐標。

  4. 如果矩形位置不在有效,並且這是需要刷新的唯一元素,則調用 invalidateContentRect() 方法。

文本選擇

如果你在使用 Android 22.2 修訂版的兼容包,懸浮工具欄不是向后兼容的,且使用默認的 ActionMode 對象。這導致懸浮工具欄無法顯示。在 AppCompatActivity 中啟用 ActionMode,首先調用 getDelegate() ,然后在返回的 AppCompatDelegate 對象中調用 setHandleNativeActionModesEnabled(),並設置輸入參數為 false。這個調用為框架返回可控的 ActionMode 對象。在運行 Android 6.0 (API 級別 23) 的設備上,這允許框架支持 ActionBar 或懸浮工具欄模式。在 Android 5.1 (API 級別 22) 或更低版本,只有 ActionBar 是支持的。

瀏覽器書簽變更

這個版本移除了對全局書簽的支持。 android.provider.Browser.getAllBookmark() 和android.provider.Browser.saveBookmark() 方法被移除。同樣的, READ_HISTORY_BOOKMARKS和 WRITE_HISTORY_BOOKMARKS 權限被移除。如果你的應用程序的目標運行版本為 Android 6.0 (API 級別 23) 或者更高,不要從全局提供者訪問書簽或者使用書簽權限。現在,你的應用程序需要內部保存書簽數據。

Android Keystore 變更

在這個版本中, Android Keystore 提供器 不在支持 DSA。 ECDSA 則仍然被支持。

當安全鎖屏被禁用或重置時,不要求加密的 key 將不再被刪除。要求加密的 key 則會在這些事件中被刪除。

Wi-Fi 和 網絡變更

這個版本為 Wi-Fi 和 網絡 API 引入了下面的行為變更:

  • 應用程序只有在創建了 WifiConfiguration 對象以后,才能更變這些對象的狀態。當 WifiConfiguration 被用戶或者其他應用程序創建時,你將不允許修改和刪除這些 WifiConfiguration 對象。
  • 在之前的版本中,如果應用程序使用 enableNetwork() ,並設置 disableAllOthers=true來強制設備連接到指定的 Wi-Fi 網絡,設備將和其他網絡斷開。這個版本中,這些設備將不再和其他網絡斷開。如果應用程序的 targetSdkVersion 是 20 或者更低,則會連接被選中的 Wi-Fi 網絡。如果應用程序的 targetSdkVersion 是 21 或者更高,使用多網絡 API (如 openConnection(), bindSocket() 及新的 bindProcessToNetwork() 方法)來確保它的網絡通信是發給被選中的網絡。

攝像頭服務變更

在這個版本中,在攝像頭服務中訪問共享資源的模式發生了變更,不再是以前的”先到先得”,而是具備高優先級的將優先處理。服務行為的變更包括:

  • 訪問攝像頭子系統的資源,包括打開和配置攝像設備,依賴於客戶端應用進程的優先級。用戶可見或者在前台活動的應用程序進程往往具備更高的優先級,使得攝像資源更易獲得,也更加可靠。

  • 當更高優先級的應用程序視圖使用攝像頭時,具有低權限的活動攝像頭客戶端應用程序可能被中斷。在被棄用的 Camera API 中,錯誤會在被中斷客戶端的 onError() 中被調用。在 Camera2 API 中,錯誤結果則在 onDisconnected() 中被調用。

  • 在具備適合攝像頭硬件的設備上,不同的應用進程可以同時獨立地打開和使用獨立的攝像頭設備。雖然如此,多進程使用時,同時訪問攝像頭會造成設備性能的急劇下降,這將被攝像頭服務所檢測到並不被允許。這個變更使得由於較低優先級而被中斷的客戶端,即使當沒有其他應用直接訪問時,也會試圖訪問一樣的設備。

  • 改變當前用戶會導致之前用戶賬號的應用程序中活動那個的攝像頭客戶端被中斷。對攝像頭的訪問是被當前設備用戶所限制的。實際上,這意味着當用戶切換到不同的賬戶下時,原來的”訪客”賬號所使用的攝像頭子系統是不可能繼續運行的。

運行時

通過 newInstance() 方法 ART 運行時現在正確的實現了訪問規則。這個變更修復了之前版本中 Dalvik 檢查訪問規則時的錯誤。如果你的應用程序使用 newInstance() 方法,且你想要覆蓋訪問檢查,調用 setAccessible() 方便,並設置參數為 true。如果你的應用程序使用 v7 兼容庫 和 v7 recyclerview 庫。你需要升級應用程序中的相關庫到最新版本。否則,需要確保 XML 中所引用的自定義類已經被升級,其構造方法是可訪問的。

這個版本升級了動態鏈接器的行為。動態連接器現在可以理解庫的 soname 和 它的路徑之間的區別,且實現了通過 soname 來搜索。在加載時,之前可用的應用程序可能會被提示具有不可用的 DT_NEEDED 條目(通常是在構建機器文件系統中的絕對路徑)。

dlopen(3) RTLD_LOCAL 標志現在被正確實現了。 RTLD_LOCAL 是默認的,因此調用dlopen(3) 是不明確使用 RTLD_LOCAL 是有效的(除非應用之前有明確使用 RTLD_GLOBAL )。使用 RTLD_LOCAL ,標記在調用 dlopen(3) 加載庫之前是不可用的(這與被 DT_NEEDED 條目引用恰恰相反)。

在之前版本的 Android,如果你的應用請求系統來加載包含文本重定位段的動態鏈接庫,系統會顯示警告,但允許繼續加載庫。從這個版本開始,如果你的目標運行 SDK 版本為 23 或以上,系統會拒絕這個庫。為了輔助檢測庫是否被成功加載,應用程序需要為 dlopen(3)失敗添加日志,並在 dlerror(3) 返回值中包含問題的描述文本。學習更多關於如何處理文本重定位段,可以查看這個指南

APK 驗證

Android 平台現在執行更加嚴格的 APK 驗證。如果一個文件在清單文件中被聲明,但在 APK 中卻沒有,那么這個 APK 被認為是無效的。如果任意的內容被移除, APK 需要重新簽名。

USB 連接

通過 USB 端口的設備連接現在默認被設置為充電模式。想要通過 USB 連接來訪問設備和它的內容,用戶需要為這些交互提供明確的授權。如果你的應用程序支持用戶通過 USB 端口與設備交互,需要確保這些交互被明確啟用。

Android for Work 變更

這個版本包括下面的 Android for Work 行為變更:

  • 個人上下文中的聯系人。Google 撥號器通話記錄現在可以在用戶查看已通話記錄時顯示當前聯系人。在 Google 撥號器中通過設置 setCrossProfileCallerIdDisabled() 為 true 來隱藏當前聯系人。當設置 setBluetoothContactSharingDisabled() 為 false 時,當前聯系人能通過藍牙顯示在設備聯系人中。默認情況下,其設置為 true

  • 移除 Wi-Fi 配置:由外部擁有者添加(如通過 addNetworkd() 方法)的 Wi-Fi 配置現在在當前 profile 被刪除時也將被移除。

  • 緊閉 Wi-Fi 配置:如果 WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN 為非空時,任何由活動的設備擁有者創建的 Wi-Fi 配置將不能用戶被修改和刪除。用戶可以創建和修改自己的 Wi-Fi 配置。活動的設備擁有者擁有編輯和移除任意 Wi-Fi 配置的特權,包括不是由他們創建的配置。

  • 通過 Google 賬號下載使用策略控制器:當一個要求 WPC 應用程序來管理的 Google 賬號被添加到管理上下文之外的設備中時,添加賬號流程會提示用戶安裝合適的 WPC。這些行為也可以應用到通過在初始設備創建向導中 設置 > 賬號 添加的賬號。

  • 制定 DevicePolicyManager API 行為變更

    • 調用 setCameraDisabled() 方法來影響當前調用用戶的攝像頭。
    • 此外, setKeyguardDisabledFeatures() 方法對 Profile 用戶是可用的,與設備擁有者一樣。
    • Profile 擁有者可以設置鍵盤守衛的約束:
      • KEYGUARD_DISABLE_TRUST_AGENTS 和 KEYGUARD_DISABLE_FINGERPRINT 將影響到 profile 父用戶的鍵盤守衛設置。
      • KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS 只會影響在 profile 中由應用程序生成的通知。
    • createAndInitializeUser() 和 createUser() 方法已經被棄用。
    • 當給定用戶的應用程序在前台運行時, setScreenCaptureDisabled() 方法將阻塞輔助結構。
    • SHA-256 的默認值為 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM 。為保持兼容性, SHA-1 仍然被支持,但在將來會被移除。 EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM 則僅接受 SHA-256。
    • 原來存在的設備初始化 API 在 Android 6.0 (API 級別 23) 中被移除了。
    • EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS 被移除,因此 NFC bump provisioning 無法通過編程的方式解鎖重置被保護的設備。
    • 現在在被管理的設備中通過 NFC 可以使用 EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE 來傳遞數據給設備擁有者的應用程序。
    • Android M 上的 Android for Work API 是經過優化的,包括 Work 配置,輔助層及其他。新的 DevicePolicyManager 權限 API 不會影響 Android 之前版本的應用程序。
    • 當用戶通過 ACTION_PROVISION_MANAGED_PROFILE 或者 ACTION_PROVISION_MANAGED_DEVICE 意圖,從創建流程中的同步部分返回時,系統將返回 RESULT_CANCELED 結果碼。
  • 其他 API 變更

    • 數據用法: android.app.usage.NetworkUsageStates 類重命名為 NetworkStats。
  • 全局設置變更
    • 下面的設置不能繼續通過 setGlobalSettings() 方法設置:
      • BLUETOOTH_ON
      • DEVELOPMENT_SETTINGS_ENABLED
      • MODE_RINGER
      • NETWORK_PREFERENCE
      • WIFI_ON
    • 下面全局設置可以通過 setGlobalSettings() 方法設置:
      • WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM