1. 程式人生 > >(轉)Android高階進階--插曲-從Android5.0到Android9.0各版本變化

(轉)Android高階進階--插曲-從Android5.0到Android9.0各版本變化

                            從Android5.0到Android9.0

           自從公司提出了一些出其不意的需求之後我就下定了決心去了解安卓各版本系統的差異。這些出其不意的需求要麼屬於黑客行為,要麼還不成熟,很難順利的實現,例如做一個殺不死的APP,又或者是一個APP可以模擬人手指隨意自動操作手機上的其它APP,例如開啟微信,控制微信聊天、控制支付寶等。這些需求都可以實現一部分,但是作為一個APP產品,從長遠來說還是很難維持下去,要麼是一個流氓軟體,要麼就是黑客軟體,試問您願意讓我開發的APP隨意去開啟,並代替您的手指自動去操作您的微信聊天,給您的好友自動傳送聊天訊息,又或者開啟支付寶付款相關頁面嗎?市面上的相關APP經過測試都不成熟,都是半瓶子水。例如代替手指自動操作手機上的其它APP,本人也能實現,但最終也許和其它市場上的APP一樣,不成熟,黑客行為,因為我需要竊取您的微信APP介面上的控制元件ID(可以理解為一個按鈕的編號)然後嘗試自動點選,這些APP最終會很難維護下去。

          在此期間也不乏有同事拿出市面上已有的APP來向我展示,貌似對我心理暗示:“看,這不是能實現嗎?是你技不如人吧”,好吧,我認了。我心中一直有這個意識:人外有人山外有山,還是認慫為秒,與其與他人爭論還不如認慫:退一步海闊天空。好了這些都扯遠了,今天的目標是給大家總結一下從Android5至Android9各版本的差異,如果你對我說的"殺不死的APP"與"自動控制APP"感興趣,我將在後續的文章中講解,或者email:   [email protected]

一、Android5
1.ANDROID 5.0 行為變更:

聲音和振動
(1)如果您當前使用 Ringtone、MediaPlayer 或 Vibrator 類向通知中新增聲音和振動,則移除此程式碼,以便系統可以在“優先”模式中正確顯示通知。取而代之的是,使用 Notification.Builder 方法新增聲音和振動。

(2)以前,Android 使用 STREAM_MUSIC 作為主流式傳輸來控制平板電腦裝置上的音量。在 Android 5.0 中,手機和平板電腦裝置的主音量流式傳輸現已合併,由 STREAM_RING 或 STREAM_NOTIFICATION 進行控制。

(3)媒體播放
       如果您要實現顯示媒體播放狀態或傳輸控制元件的通知,請考慮使用新的 Notification.MediaStyle 模板,而不是自定義 RemoteViews.Remote View 物件。無論您選擇使用哪個方法,請務必將通知的可見性設為 VISIBILITY_PUBLIC,以便可通過鎖定螢幕訪問您的控制元件。請注意,從 Android 5.0 開始,系統不再將 RemoteControlClient 物件顯示在鎖定螢幕上。如需瞭解詳細資訊,請參閱如果您的應用使用 RemoteControlClient.
       
(4)浮動通知               

現在,當裝置處於活動狀態時(即,裝置未鎖定且其螢幕已開啟),通知可以顯示在小型浮動視窗中(也稱為“浮動通知”)。這些通知看上去類似於精簡版的通知,只是浮動通知還顯示操作按鈕。使用者可以在不離開當前應用的情況下處理或清除浮動通知。
可能觸發浮動通知的條件示例包括:
使用者的 Activity 處於全屏模式中(應用使用 fullScreenIntent)
通知具有較高的優先順序並使用鈴聲或振動。

(5)繫結到服務
Context.bindService() 方法現在需要顯式 Intent,如果提供隱式 intent,將引發異常。為確保應用的安全性,請使用顯式 intent 啟動或繫結 Service,且不要為服務宣告 intent 過濾器。


(6)WebView
Android 5.0 更改了應用的預設行為。
如果您的應用是面向 API 級別 21 或更高級別:
預設情況下,系統會阻止混合內容和第三方 Cookie。要允許混合內容和第三方 Cookie,請分別使用 setMixedContentMode() 和 setAcceptThirdPartyCookies() 方法。
系統現在可以智慧地選擇要繪製的 HTML 文件部分。這個新的預設行為有助於減少記憶體佔用和提升效能。如果您要一次渲染整個文件,可通過呼叫 enableSlowWholeDocumentDraw() 停用此優化。
如果您的應用是面向低於 21 的 API 級別:系統允許混合內容和第三方 Cookie,並始終一次渲染整個文件。

(7)自定義許可權
從 Android 5.0 開始,對於使用不同金鑰簽名的應用,系統會強制執行新的自定義許可權唯一性限制。現在,裝置上只有一個應用可以定義給定的自定義許可權(按其名稱確定),除非定義此許可權的其他應用使用相同金鑰簽名

(8)
與伺服器握手的 TLS/SSL 被錯誤地拒絕或出現停頓。首選的修復方法是升級伺服器以符合 TLS/SSL 協議


2. ANDROID 5.0 API變更:

(1)  WebView 更新

Android 5.0 將 WebView 實現更新至 Chromium M37,增強了安全性和穩定性,並修復了一些問題。執行在 Android 5.0 上的 WebView 的預設使用者代理字串已更新,以納入 37.0.0.0 作為版本號。

此版本引入了 PermissionRequest 類,讓您的應用可以通過 getUserMedia()open_in_new 等網路 API 授予 WebView 訪問相機和麥克風之類受保護資源的許可權。您的應用必須對這些資源擁有相應的 Android 許可權,才能向 WebView 授予許可權。

藉助新的 onShowFileChooser() 方法,您現在可以在 WebView 中使用輸入表單欄位,然後啟動檔案選擇器從 Android 裝置中選擇影象和檔案。

此外,此版本還提供了對 WebAudioopen_in_new、WebGLopen_in_new 和 WebRTCopen_in_new 開放標準的支援。要詳細瞭解此版本包含的新功能,請參閱 WebView for Androidopen_in_new。

(2).螢幕採集和共享

Android 5.0 引入了新的 android.media.projection API,讓您可以為應用新增螢幕採集和螢幕共享功能。例如,如果您想在視訊會議應用中啟用螢幕共享,便可使用此功能。

新增的 createVirtualDisplay() 方法允許您的應用將主螢幕(預設顯示)的內容採集到一個 Surface 物件中,然後您的應用便可將其傳送至整個網路。該 API 只允許採集非安全螢幕內容,不允許採集系統音訊。要開始採集螢幕,您的應用必須先使用通過 createScreenCaptureIntent() 方法獲得的 Intent 啟動螢幕採集對話方塊,請求使用者授予許可權。
如需檢視新 API 使用方法的示例,請參閱示例專案中的 MediaProjectionDemo 類。


(3). 使用者介面
Material Design 支援
Android 5.0 添加了對 Android 的新 Material Design 樣式的支援。您可以建立具有 Material Design 功能的應用,實現動態視覺效果,利用其中的 UI 元素轉換賦予使用者自然的感覺。此支援包括:
----------------------------------------------------------------------------------------------
Material Design 支援
Android 5.0 添加了對 Android 的新 Material Design 樣式的支援。您可以建立具有 Material Design 功能的應用,實現動態視覺效果,利用其中的 UI 元素轉換賦予使用者自然的感覺。此支援包括:
Material Design 主題
檢視陰影
RecyclerView 小部件
可繪製動畫和造型效果
Material Design 動畫和 Activity 轉換效果
針對基於檢視狀態的檢視屬性的動畫生成器
可自定義的 UI 小部件和具有可由您控制的調色盤的應用欄
基於 XML 向量圖形的動畫和非動畫可繪製物件

(4).通知

鎖定螢幕通知
Android 5.0 中的鎖定螢幕可以顯示通知。使用者可以通過“Settings” 選擇是否允許在安全的鎖定螢幕上顯示敏感的通知內容。

您的應用可以控制在安全鎖定螢幕上顯示的通知中可見資訊的詳細程度。要控制可見性級別,請呼叫 setVisibility(),然後指定以下值之一:
VISIBILITY_PRIVATE:顯示通知圖示等基本資訊,但隱藏通知的完整內容。
?VISIBILITY_PUBLIC:顯示通知的完整內容。
VISIBILITY_SECRET:不顯示任何內容,甚至不顯示通知圖示。

當可視性級別為 VISIBILITY_PRIVATE 時,您還可以提供隱藏個人詳情的刪減版通知內容。例如,簡訊應用可能會顯示一條通知,指出“您有3 條新簡訊”,但是隱藏了簡訊內容和發件人。要提供此替換版本的通知,請先使用 Notification.Builder 建立替換通知。建立專用通知物件時,請通過 setPublicVersion() 方法為其附加替換通知。

通知元資料
Android 5.0 使用與您的應用通知關聯的元資料,以更智慧的方式對通知排序。要設定元資料,請在構建通知時呼叫 Notification.Builder 中的下列方法:

setCategory():當裝置處於“優先”模式時,指示系統如何處理應用通知(例如,通知代表來電、即時通訊還是鬧鈴)。
setPriority():標記通知的重要性是高於還是低於普通通知。如果優先順序欄位設定為 PRIORITY_MAX 或PRIORITY_HIGH 的通知還有聲音或振動,則會將其顯示在小型浮動視窗中。
addPerson():讓您可以新增一名或多名與通知有關的人員。您的應用可以使用此名單指示系統將指定人員發出的通知歸成一組,或者將這些人員發出的通知視為更重要的通知。

(5).對 OpenGL ES 3.1 的支援

(6).媒體

用於高階相機功能的 Camera API

Android 5.0 引入了新的 android.hardware.camera2 API 來簡化精細照片採集和影象處理。您現在可以使用 getCameraIdList() 通過程式設計方式訪問可供系統使用的相機裝置,以及使用 openCamera() 通過程式設計方式連線特定裝置。要開始採集影象,請建立一個 CameraCaptureSession 並指定用於傳送已採集影象的 Surface 物件。可將 CameraCaptureSession 配置為進行單張拍攝或多張連拍。

要在採集新影象時得到通知,請實現 CameraCaptureSession.CaptureCallback 偵聽器,並在您的採集請求中進行設定。現在,當系統完成影象採集請求時,您的 CameraCaptureSession.CaptureCallback 偵聽器會收到對 onCaptureCompleted() 的呼叫,並在 CaptureResult 中為您提供影象採集元資料。

CameraCharacteristics 類可讓您的應用檢測到裝置上可用的相機功能。該物件的 INFO_SUPPORTED_HARDWARE_LEVEL 屬性代表相機的功能級別。

所有裝置都至少支援 INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY 硬體級別,該級別具有的能力大致與棄用的 Camera API 相當。
支援 INFO_SUPPORTED_HARDWARE_LEVEL_FULL 硬體級別的裝置可手動控制採集和後期處理,以及以高幀速率採集高解析度影象。
要了解如何使用更新後的 Camera API,請參閱此版本中的 Camera2Basic 和 Camera2Video 實現示例。

(7).音訊回放

此版本加入了對 AudioTrack 的下列更改:

您的應用現在可以提供浮點格式 (ENCODING_PCM_FLOAT) 的音訊資料。這可以實現更大的動態範圍、更一致的精度和更多的動態餘量。浮點演算法在進行中間計算時特別有用。回放端點為音訊資料使用位深度更低的整型格式。(在Android 5.0中,部分內部管道尚未採用浮點格式。)
您的應用現在可以提供音訊資料作為 ByteBuffer,資料使用的格式與 MediaCodec 提供的格式相同。
WRITE_NON_BLOCKING 選項可簡化某些應用的緩衝和多執行緒處理。


(8) 媒體回放控制

使用新增的通知和媒體 API 可確保系統 UI 瞭解您的媒體回放情況,並可提取和顯示專輯封面。現在,可以利用新增的 MediaSession 類和 MediaController 類更輕鬆地在整個 UI 和服務範圍內控制媒體回放。

新增的 MediaSession 類替代了棄用的 RemoteControlClient 類,僅提供一套回撥方法來處理傳輸控制和媒體按鈕。如果您的應用提供媒體回放,並執行在 Android TV 或 Wear 平臺上,請使用 MediaSession 類,通過同樣的回撥方法來處理您的傳輸控制。

現在,您可以使用新增的 MediaController 類開發自己的媒體控制器應用。該類可通過您的應用的 UI 程序,以執行緒安全方式監控和控制媒體回放。請在建立控制器時指定一個 MediaSession.Token 物件,以便您的應用可與給定 MediaSession 互動。您可以利用 MediaController.TransportControls 方法,通過傳送 play()、stop()、skipToNext() 和 setRating() 等命令來控制該會話上的媒體回放。對於控制器,您還可以註冊一個 MediaController.Callback 物件來偵聽該會話上的元資料和狀態變化。

此外,您還可以利用新增的 Notification.MediaStyle 類建立允許將回放控制與媒體會話繫結的豐富通知


(9).媒體瀏覽

Android 5.0 引入了通過新增的 android.media.browse API 讓應用能夠瀏覽其他應用媒體內容庫的功能。要公開您應用內的媒體內容,請擴充套件 MediaBrowserService 類。您實現的 MediaBrowserService 應提供對 MediaSession.Token 的訪問許可權,以便應用能播放通過您的服務提供的媒體內容。

要與媒體瀏覽器服務互動,請使用 MediaBrowser 類。在您建立 MediaBrowser 例項時為 MediaSession 指定元件名稱。然後,您的應用便可利用該瀏覽器例項連線到關聯的服務並獲得 MediaSession.Token 物件,以播放通過該服務公開的內容。

(10).無線和連線

多個網路連線

Android 5.0 提供了新的多網路 API,允許您的應用動態掃描具有特定能力的可用網路,並與它們建立連線。當您的應用需要 SUPL、彩信或運營商計費網路等專業化網路時,或者您想使用特定型別的傳輸協議傳送資料時,就可以使用此功能。

要從您的應用以動態方式選擇並連線網路,請執行以下步驟:

建立一個 ConnectivityManager。
使用 NetworkRequest.Builder 類建立一個 NetworkRequest 物件,並指定您的應用感興趣的網路功能和傳輸型別。
要掃描合適的網路,請呼叫 requestNetwork() 或 registerNetworkCallback(),並傳入 NetworkRequest 物件和 ConnectivityManager.NetworkCallback 的實現。如果您想在檢測到合適的網路時主動切換到該網路,請使用 requestNetwork() 方法;如果只是接收已掃描網路的通知而不需要主動切換,請改用 registerNetworkCallback() 方法。
當系統檢測到合適的網路時,它會連線到該網路並呼叫 onAvailable() 回撥。您可以使用回撥中的 Network 物件來獲取有關網路的更多資訊,或者引導通訊使用所選網路。

(11). 藍芽低功耗

Android 4.3 為發揮核心作用的藍芽低功耗(藍芽 LE)引入了平臺支援。在 Android 5.0 中,Android 裝置現在可以發揮藍芽 LE 外圍裝置的作用。應用可以利用此功能讓附近裝置發現它。例如,您可以開發這樣的應用:讓裝置發揮計步器或健康監測儀的作用,並與其他藍芽 LE 裝置進行資料通訊。

新增的 android.bluetooth.le API 讓您的應用可以釋出廣告、掃描響應以及與附近的藍芽 LE 裝置建立連線。要使用新增的廣告和掃描功能,請在您的清單中新增 BLUETOOTH_ADMIN 許可權。當用戶更新您的應用或從 Play 商店下載您的應用時,會被要求向您的應用授予以下許可權:“Bluetooth connection information:Allows the app to control Bluetooth, including broadcasting to or getting information about nearby Bluetooth devices.”

要啟動藍芽 LE 廣播,以便其他裝置能發現您的應用,請呼叫 startAdvertising(),並傳入 AdvertiseCallback 類的實現。回撥物件會收到廣播操作成功或失敗的報告。

Android 5.0 引入了 ScanFilter 類,讓您的應用可以只掃描其感興趣的特定型別裝置。要開始掃描藍芽 LE 裝置,請呼叫 startScan(),並傳入篩選器列表。在方法呼叫中,您還必須提供 ScanCallback 的實現,以便在發現藍芽 LE 廣播時進行報告。


(12)  計劃排定作業JobScheduler

Android 5.0 新增了一個 JobScheduler API,允許您定義一些系統在稍後或指定條件下(如裝置充電時)以非同步方式執行的作業,從而優化電池壽命。下列情形下,作業計劃排定功能很有用:

應用具有不面向使用者並且可以推遲的作業
應用具有您更願意在裝置插入電源時再進行的作業
應用具有一項需要接入網路或連線 WLAN 的任務。
應用具有多項您希望定期以批處理方式執行的任務。
一個作業單位由一個 JobInfo 物件封裝。該物件指定計劃排定標準。

使用 JobInfo.Builder 類可配置應如何執行已排計劃的任務。您可以安排任務在特定條件下執行,例如:

在裝置充電時啟動
在裝置連入無限流量網路時啟動
在裝置空閒時啟動
在特定期限前或以最低延遲完成
例如,您可以新增一段如下程式碼,在無限流量網路上執行您的任務:

JobInfo uploadTask = new JobInfo.Builder(mJobId,
                                         mServiceComponent /* JobService component */)
        .setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED)
        .build();
JobScheduler jobScheduler =
        (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(uploadTask);
如果裝置有穩定的電源(也就是說,裝置已插入電源超過 2 分鐘,並且電池處於健康水平),系統將執行任何已做好執行準備的計劃作業,無論作業期限是否已過。

要檢視如何使用 JobScheduler API 的示例,請參閱此版本中的 JobSchedulerSample 實現示例。

(13)固定螢幕

Android 5.0 引入了一個全新的固定螢幕 API,可讓您暫時限制使用者離開您的任務或被通知打斷。舉例來說,如果您要開發一款教育應用來支援 Android 上的高風險評估要求,或者您要開發單一用途或資訊亭模式下的應用,便可使用此 API。您的應用啟用固定屏幕後,在其退出該模式前,使用者將無法看到通知,無法訪問其他應用,也無法返回主螢幕。

啟用固定螢幕的方式有兩種:

手動方式:使用者可以在 Settings > Security > Screen Pinning 中啟用固定螢幕,然後通過觸控最近使用的應用螢幕中的綠色大頭針圖示選擇其想固定的任務。
程式設計方式:要以程式設計方式啟用固定螢幕,請在您的應用內呼叫 startLockTask()。如果請求應用不是裝置所有者,系統會提示使用者進行確認。裝置所有者應用可以呼叫 setLockTaskPackages() 方法,無需執行使用者確認步驟便可使應用變為可固定應用。
啟用任務鎖定時,會發生以下行為:

狀態列空白,並隱藏使用者通知和狀態資訊。
“主螢幕”按鈕和“最近用過的應用”按鈕處於隱藏狀態。
其他應用無法啟動新 Activity
當前應用可以啟動新 Activity,前提是這樣做不會建立新任務。
當裝置所有者呼叫固定螢幕時,使用者將一直鎖定於您的應用,直至應用呼叫 stopLockTask()。
如果固定螢幕是由並非裝置所有者的其他應用啟動的 Activity,或者是由使用者直接啟動,則使用者可通過同時按住“Back”按鈕和“Recent”按鈕退出。


(14)可宣告的必備功能

現在支援在 <uses-feature> 元素中使用以下值,以便您確保只在提供應用所需功能的裝置上安裝您的應用

(15)使用者許可權

現在,<uses-permission> 元素中支援以下許可權,以宣告您的應用訪問特定 API 所需的許可權。

BIND_DREAM_SERVICE:如果針對的是 API 級別 21 及更高級別,則互動屏保服務必須獲得該許可權才能確保只有系統可與其繫結。


二、ANDROID 6.0

1. 行為變更

(1)  執行時許可權

此版本引入了一種新的許可權模式,如今,使用者可直接在執行時管理應用許可權。這種模式讓使用者能夠更好地瞭解和控制權限,同時為應用開發者精簡了安裝和自動更新過程。使用者可為所安裝的各個應用分別授予或撤銷許可權。

對於以 Android 6.0(API 級別 23)或更高版本為目標平臺的應用,請務必在執行時檢查和請求許可權。要確定您的應用是否已被授予許可權,請呼叫新增的 checkSelfPermission() 方法。要請求許可權,請呼叫新增的 requestPermissions() 方法。即使您的應用並不以 Android 6.0(API 級別 23)為目標平臺,您也應該在新許可權模式下測試您的應用。

如需瞭解有關在您的應用中支援新許可權模式的詳情,請參閱使用系統許可權。如需瞭解有關如何評估新模式對應用的影響的提示,請參閱許可權最佳做法。


(2)  低電耗模式和應用待機模式

此版本引入了針對空閒裝置和應用的最新節能優化技術。這些功能會影響所有應用,因此請務必在這些新模式下測試您的應用。

低電耗模式:如果使用者拔下裝置的電源插頭,並在螢幕關閉後的一段時間內使其保持不活動狀態,裝置會進入低電耗模式,在該模式下裝置會嘗試讓系統保持休眠狀態。在該模式下,裝置會定期短時間恢復正常工作,以便進行應用同步,還可讓系統執行任何掛起的操作。
應用待機模式:應用待機模式允許系統判定應用在使用者未主動使用它時處於空閒狀態。當用戶有一段時間未觸控應用時,系統便會作出此判定。如果拔下了裝置電源插頭,系統會為其視為空閒的應用停用網路訪問以及暫停同步和作業。
要詳細瞭解這些節能變更,請參閱對低電耗模式和應用待機模式進行鍼對性優化。

(3)取消支援 Apache HTTP 客戶端

Android 6.0 版移除了對 Apache HTTP 客戶端的支援。如果您的應用使用該客戶端,並以 Android 2.3(API 級別 9)或更高版本為目標平臺,請改用 HttpURLConnection 類。此 API 效率更高,因為它可以通過透明壓縮和響應快取減少網路使用,並可最大限度降低耗電量。要繼續使用 Apache HTTP API,您必須先在 build.gradle 檔案中宣告以下編譯時依賴項:

android {
    useLibrary 'org.apache.http.legacy'
}


(4)BoringSSL

Android 正在從使用 OpenSSL 庫轉向使用 BoringSSL 庫。如果您要在應用中使用 Android NDK,請勿連結到並非 NDK API 組成部分的加密庫,如 libcrypto.so 和 libssl.so。這些庫並非公共 API,可能會在不同版本和裝置上毫無徵兆地發生變化或出現故障。此外,您還可能讓自己暴露在安全漏洞的風險之下。請改為修改原生程式碼,以通過 JNI 呼叫 Java 加密 API,或靜態連結到您選擇的加密庫。

(5) 藍芽掃描需要定位許可權 才能獲得MAC地址,硬體識別符號訪問權

為給使用者提供更嚴格的資料保護,從此版本開始,對於使用 WLAN API 和 Bluetooth API 的應用,Android 移除了對裝置本地硬體識別符號的程式設計訪問權。WifiInfo.getMacAddress() 方法和 BluetoothAdapter.getAddress() 方法現在會返回常量值 02:00:00:00:00:00。

現在,要通過藍芽和 WLAN 掃描訪問附近外部裝置的硬體識別符號,您的應用必須擁有 ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION 許可權。

WifiManager.getScanResults()
BluetoothDevice.ACTION_FOUND
BluetoothLeScanner.startScan()
注:當執行 Android 6.0(API 級別 23)的裝置發起後臺 WLAN 或藍芽掃描時,在外部裝置看來,該操作的發起來源是一個隨機化 MAC 地址。

(6) 通知
此版本移除了 Notification.setLatestEventInfo() 方法。請改用 Notification.Builder 類來構建通知。要重複更新通知,請重複使用 Notification.Builder 例項。呼叫 build() 方法可獲取更新後的 Notification 例項。

adb shell dumpsys notification 命令不再列印輸出您的通知文字。請改用 adb shell dumpsys notification --noredact 命令列印輸出 notification 物件中的文字。

(7)音訊管理器變更

不再支援通過 AudioManager 類直接設定音量或將特定音訊流靜音。setStreamSolo() 方法已棄用,您應該改為呼叫 requestAudioFocus() 方法。類似地,setStreamMute() 方法也已棄用,請改為呼叫 adjustStreamVolume() 方法並傳入方向值 ADJUST_MUTE 或 ADJUST_UNMUTE。


(8)WLAN 和網路連線變更
此版本對 WLAN API 和 Networking API 引入了以下行為變更。

現在,您的應用只能更改由您建立的 WifiConfiguration 物件的狀態。系統不允許您修改或刪除由使用者或其他應用建立的 WifiConfiguration 物件。
在之前的版本中,如果應用利用帶有 disableAllOthers=true 設定的 enableNetwork() 強制裝置連線特定 WLAN 網路,裝置將會斷開與移動資料網路等其他網路的連線。在此版本中,裝置不再斷開與上述其他網路的連線。如果您的應用的 targetSdkVersion 為 “20” 或更低,則會固定連線所選 WLAN 網路。如果您的應用的 targetSdkVersion 為 “21” 或更高,請使用多網路 API(如 openConnection()、bindSocket() 和新增的 bindProcessToNetwork() 方法)來確保通過所選網路傳送網路流量。

(9)相機服務變更

在此版本中,相機服務中共享資源的訪問模式已從之前的“先到先得”訪問模式更改為高優先順序程序優先的訪問模式。對服務行為的變更包括:

根據客戶端應用程序的“優先順序”授予對相機子系統資源的訪問權,包括開啟和配置相機裝置。帶有對使用者可見 Activity 或前臺 Activity 的應用程序一般會被授予較高的優先順序,從而使相機資源的獲取和使用更加可靠;

當高優先順序的應用嘗試使用相機時,系統可能會“驅逐”正在使用相機客戶端的低優先順序應用。在已棄用的 Camera API 中,這會導致系統為被驅逐的客戶端呼叫 onError()。在 Camera2 API 中,這會導致系統為被驅逐的客戶端呼叫 onDisconnected();

在配備相應相機硬體的裝置上,不同的應用程序可同時獨立開啟和使用不同的相機裝置。但現在,如果在多程序用例中同時訪問相機會造成任何開啟的相機裝置的效能或能力嚴重下降,相機服務會檢測到這種情況並禁止同時訪問。即使並沒有其他應用直接嘗試訪問同一相機裝置,此變更也可能導致低優先順序客戶端被“驅逐”。


更改當前使用者會導致之前使用者帳戶擁有的應用內活動相機客戶端被驅逐。對相機的訪問僅限於訪問當前裝置使用者擁有的使用者個人資料。舉例來說,這意味著,當用戶切換到其他帳戶後,“來賓”帳戶實際上無法讓使用相機子系統的程序保持執行狀態

(10)執行時

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) 呼叫返回的問題描述文字。要詳細瞭解如何處理文字重定位,請參閱此指南。


(11)APK 驗證

該平臺現在執行的 APK 驗證更為嚴格。如果在清單中宣告的檔案在 APK 中並不存在,該 APK 將被視為已損壞。移除任何內容後必須重新簽署 APK。

(12)USB 連線

預設情況下,現在通過 USB 埠進行的裝置連線設定為僅充電模式。要通過 USB 連線訪問裝置及其內容,使用者必須明確地為此類互動授予許可權。如果您的應用支援使用者通過 USB 埠與裝置進行互動,請將必須顯式啟用互動考慮在內

2.ANDROID 6.0 API 變更

1. 指紋身份驗證

此版本提供了一些新的 API,在受支援的裝置上,使用者只需掃描其指紋即可完成身份驗證,這些 API 還可與 Android 金鑰庫系統結合使用。

要通過指紋掃描驗證使用者身份,請獲取新 FingerprintManager 類的例項,並呼叫 authenticate()方法。您的應用必須執行在帶有指紋感測器的相容裝置上。您必須在應用中實現指紋身份驗證流的使用者介面,並在 UI 中使用標準 Android 指紋圖示。FingerprintDialog 示例中包含有 Android 指紋圖示 (c_fp_40px.png)。請注意,如果您要開發多個使用指紋身份驗證的應用,每個應用必須獨立驗證使用者的指紋。

要在您的應用中使用此功能,請先在清單中新增 USE_FINGERPRINT 許可權。

<uses-permission
        android:name="android.permission.USE_FINGERPRINT" />

要檢視指紋身份驗證的應用實現,請參閱FingerprintDialog 示例。要檢視有關將這些身份驗證 API 與其他 Android API 結合使用方法的演示,請觀看視訊 Fingerprint API 和 Payment API。


2.確認憑據

您的應用可以根據使用者在多久之前最後一次解鎖裝置來驗證其身份。此功能讓使用者不必費心記憶應用特定密碼,您也無需實現自己的身份驗證使用者介面。您的應用應當利用此功能並結合實現公鑰或私鑰,以進行使用者身份驗證。

要設定成功驗證使用者身份後可再次使用同一金鑰的超時持續時間,請在設定 KeyGenerator 或 KeyPairGenerator 時呼叫新增的 setUserAuthenticationValidityDurationSeconds() 方法。

避免過多顯示重新驗證對話方塊 -- 您的應用應嘗試先使用加密物件,如果超時到期,請使用 createConfirmDeviceCredentialIntent() 方法在您的應用內重新驗證使用者身份。

要檢視此功能的應用實現,請參閱 ConfirmCredential 示例。


3.直接共享
此版本為您提供的一些 API 可讓使用者直觀、快捷地進行共享。現在,您可以定義可在您的應用內啟動特定 Activity 的直接共享目標。這些直接共享目標通過“共享”選單公開給使用者。此功能讓使用者可以向其他應用內的目標(如聯絡人)共享內容。例如,直接共享目標可以啟動另一社交網路應用中的某個 Activity,讓使用者可以直接向該應用中的某位朋友或某個社群共享內容。

要啟用直接共享目標,您必須定義一個類,用於擴充套件 ChooserTargetService 類。在清單中宣告您的服務。在該宣告內,指定 BIND_CHOOSER_TARGET_SERVICE 許可權和一個使用 SERVICE_INTERFACE 操作的 intent 過濾器。

以下示例展示瞭如何在清單中宣告 ChooserTargetService。

<service android:name=".ChooserTargetService"
        android:label="@string/service_name"
        android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
    <intent-filter>
        <action android:name="android.service.chooser.ChooserTargetService" />
    </intent-filter>
</service>
對於您想要向 ChooserTargetService 公開的每個 Activity,請在您的應用清單中為其新增一個名為 "android.service.chooser.chooser_target_service" 的 <meta-data> 元素。

<activity android:name=".MyShareActivity”
        android:label="@string/share_activity_label">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
    </intent-filter>
<meta-data
        android:name="android.service.chooser.chooser_target_service"
        android:value=".ChooserTargetService" />
</activity>

4. 語音互動

此版本提供了一個新的語音互動 API,與語音操作一起使用時,可讓您為應用打造對話式語音體驗。呼叫 isVoiceInteraction() 方法可確定是否是響應語音操作觸發了您的 Activity。如果是這樣,則您的應用可以使用 VoiceInteractor 類請求使用者進行語音確認、從選項列表中進行選擇以及執行其他操作。

大多數語音互動都由使用者語音操作發起。但語音互動 Activity 也可在沒有使用者輸入的情況下啟動。例如,通過語音互動啟動的另一應用也可傳送 intent 來啟動語音互動。要確定您的 Activity 是由使用者語音查詢還是另一語音互動應用啟動,請呼叫 isVoiceInteractionRoot() 方法。如果另一應用啟動了您的 Activity,該方法會返回 false。您的應用可能隨即提示使用者確認其有意執行此操作。


5. 可採用的儲存裝置

使用此版本時,使用者可以採用 SD 卡等外部儲存裝置。採用外部儲存裝置可加密和格式化裝置,使其具有類似內部儲存裝置的行為。使用者可以利用此特性在儲存裝置之間移動應用及其私有資料。移動應用時,系統會遵守清單中的 android:installLocation 首選項。

請注意,在內部儲存裝置與外部儲存裝置之間移動應用時,如果您的應用訪問以下 API 或欄位,它們返回的檔案路徑將會動態變化。強烈建議:在生成檔案路徑時,請始終動態呼叫這些 API。請勿使用硬編碼檔案路徑或之前生成的永久性完全限定檔案路徑。

Context 方法:
getFilesDir()
getCacheDir()
getCodeCacheDir()
getDatabasePath()
getDir()
getNoBackupFilesDir()
getFileStreamPath()
getPackageCodePath()
getPackageResourcePath()
ApplicationInfo 欄位:
dataDir
sourceDir
nativeLibraryDir
publicSourceDir
splitSourceDirs
splitPublicSourceDirs


6. 通知
此版本針對通知功能引入了下列 API 變更:
新增了 INTERRUPTION_FILTER_ALARMS 過濾級別,它對應於新增的“僅鬧鈴”免打擾模式。
新增了 CATEGORY_REMINDER 類別值,用於區分使用者安排的提醒與其他事件 (CATEGORY_EVENT) 和鬧鈴 (CATEGORY_ALARM)。
新增了 Icon 類,您可以通過 setSmallIcon()方法和 setLargeIcon()方法將其附加到通知上。同理,addAction() 方法現在接受 Icon 物件,而不接受可繪製資源 ID。
新增了 getActiveNotifications() 方法,讓您的應用能夠了解哪些通知目前處於活動狀態。要檢視使用此功能的應用實現,請參閱 ActiveNotifications 示例。


7.改進的藍芽低功耗掃描
如果您的應用執行藍芽低功耗掃描,可以使用新增的 setCallbackType() 方法指定您只希望在下列條件下通知回撥:首次找到與設定的 ScanFilter 匹配的播發資料包,或者已過很長時間後才再次看到該資料包。這種掃描方法與舊平臺版本中提供的方法相比更加節能。

8.  Hotspot 2.0 第 1 版支援

9.  4K 顯示模式

10.主題化 ColorStateList

對於執行 Android 6.0(API 級別 23)的裝置,現在支援在 ColorStateList 中使用主題屬性。Resources.getColorStateList() 方法和 Resources.getColor() 方法已棄用。如果您要呼叫這些 API,請改為呼叫新增的 Context.getColorStateList() 方法或 Context.getColor() 方法。還可在 v4 appcompat 庫中通過 ContextCompat 使用這些方法。

11.視訊功能

此版本為視訊處理 API 添加了新功能,包括:

新增了 MediaSync 類,可幫助應用同步渲染音訊流和視訊流。音訊緩衝區以非鎖定方式提交,並通過回撥返回。此外,它還支援動態回放速率。
新增了 EVENT_SESSION_RECLAIMED 事件,它表示應用開啟的會話已被資源管理器收回。如果您的應用使用 DRM 會話,則應處理此事件,並確保不使用收回的會話。
新增了 ERROR_RECLAIMED 錯誤程式碼,它表示資源管理器收回了編解碼器使用的媒體資源。出現此異常時,必須釋放編解碼器,因為它已轉入終止狀態。
新增了 getMaxSupportedInstances() 介面,用於獲取有關支援的編解碼器例項最大併發數量的提示。
新增了 setPlaybackParams() 方法,用於設定快動作回放或慢動作回放的媒體回放速率。此外,它還會隨視訊一起自動拉長或加速音訊回放


12.低電耗模式限制
在低電耗模式下,您的應用會受到以下限制:

暫停訪問網路。
系統將忽略 wake locks。
標準 AlarmManager 鬧鈴(包括 setExact() 和 setWindow())推遲到下一維護時段。
如果您需要設定在低電耗模式下觸發的鬧鈴,請使用 setAndAllowWhileIdle() 或 setExactAndAllowWhileIdle()。
一般情況下,使用 setAlarmClock() 設定的鬧鈴將繼續觸發 — 但系統會在這些鬧鈴觸發之前不久退出低電耗模式。
系統不執行 Wi-Fi 掃描。
系統不允許運行同步介面卡。
系統不允許執行 JobScheduler。


13. 瞭解應用待機模式
應用待機模式允許系統判定應用在使用者未主動使用它時處於空閒狀態。 當用戶有一段時間未觸控應用時,系統便會作出此判定,以下條件均不適用:

使用者顯式啟動應用。
應用當前有一個程序位於前臺(表現為 Activity 或前臺服務形式,或被另一 Activity 或前臺服務佔用)。
應用生成使用者可在鎖屏或通知托盤中看到的通知。
當用戶將裝置插入電源時,系統將從待機狀態釋放應用,從而讓它們可以自由訪問網路並執行任何待定作業和同步。 如果裝置長時間處於空閒狀態,系統將按每天大約一次的頻率允許空閒應用訪問網路。

14.在裝置空閒時使用 GCM 與您的應用互動
Google Cloud Messaging (GCM) 是一項雲端至裝置的服務,允許您支援在後端服務與 Android 裝置上的應用之間實時進行下游訊息傳遞。GCM 提供了單一持久的雲連線;所有需要實時傳遞訊息的應用均可共享此連線。此共享連線使多個應用無需消耗電池即可維持自身單獨的持久連線,避免快速耗盡電池,從而顯著優化電池消耗。 因此,如果應用需要與後端服務進行訊息傳遞整合,我們強烈建議您儘量使用 GCM,而非維持自身持久的網路連線。

GCM 經過優化,可通過高優先順序 GCM 訊息用於低電耗模式和應用待機模式。GCM 高優先順序訊息允許您可靠地喚醒應用訪問網路,即使使用者裝置處於低電耗模式或應用處於應用待機模式也不例外。 在低電耗模式或應用待機模式下,系統將傳遞訊息並允許應用臨時訪問網路服務和部分喚醒鎖,然後將裝置或應用恢復到空閒狀態。

高優先順序 GCM 訊息不會影響低電耗模式,也不會影響任何其他應用的狀態。這意味著您的應用可以使用這些訊息進行有效的通訊,同時儘可能減少對整個系統和裝置的電池影響。

作為一項常規最佳做法,如果您的應用需要下游訊息傳遞,則應使用 GCM。如果您的伺服器和客戶端已經使用 GCM,請確保服務對關鍵訊息使用高優先順序訊息,因為即使裝置處於低電耗模式,這也會可靠地喚醒應用


15.對其他用例的支援
通過妥善管理網路連線、鬧鈴、作業和同步並使用 GCM 高優先順序訊息,幾乎所有應用都應該能夠支援低電耗模式。對於一小部分用例,這可能還不夠。 對於此類用例,系統為部分免除低電耗模式和應用待機模式優化的應用提供了一份可配置的白名單。

在低電耗模式和應用待機模式期間,加入白名單的應用可以使用網路並保留部分 wake locks。 不過,正如其他應用一樣,其他限制仍然適用於加入白名單的應用。 例如,加入白名單的應用的作業和同步將推遲(在 API 級別 23 及更低級別中),並且其常規 AlarmManager 鬧鈴不會觸發。通過呼叫 isIgnoringBatteryOptimizations(),應用可以檢查自身當前是否位於豁免白名單中。

使用者可以在 Settings > Battery > Battery Optimization 中手動配置該白名單。或者,系統會為應用提供請求使用者將應用加入白名單的方式。

應用可以觸發 ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS Intent,讓使用者直接進入 Battery Optimization,他們可以在其中新增應用。
具有 REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 許可權的應用可以觸發系統對話方塊,讓使用者無需轉到“設定”即可直接將應用新增到白名單。應用將通過觸發 ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS Intent 來觸發該對話方塊。
使用者可以根據需要手動從白名單中移除應用。
在請求使用者將應用新增到白名單之前,請確保應用符合加入白名單的可接受用例。


16.在低電耗模式和應用待機模式下進行測試
為了確保使用者獲得極佳體驗,您應在低電耗模式和應用待機模式下全面測試您的應用。

在低電耗模式下測試您的應用
您可按以下步驟測試低電耗模式:

使用 Android 6.0(API 級別 23)或更高版本的系統映像配置硬體裝置或虛擬裝置。
將裝置連線到開發計算機並安裝應用
執行應用並使其保持活動狀態
關閉裝置螢幕。(應用保持活動狀態。)
通過執行以下命令強制系統在低電耗模式之間迴圈切換:
$ adb shell dumpsys battery unplug
$ adb shell dumpsys deviceidle step
您可能需要多次執行第二個命令。不斷地重複,直到裝置變為空閒狀態。

在重新啟用裝置後觀察應用的行為。確保應用在裝置退出低電耗模式時正常恢復。
在應用待機模式下測試您的應用
要在應用待機模式下測試您的應用,請執行以下操作:

使用 Android 6.0(API 級別 23)或更高版本的系統映像配置硬體裝置或虛擬裝置。
將裝置連線到開發計算機並安裝應用
執行應用並使其保持活動狀態
通過執行以下命令強制應用進入應用待機模式:
$ adb shell dumpsys battery unplug
$ adb shell am set-inactive <packageName> true
使用以下命令模擬喚醒應用:
$ adb shell am set-inactive <packageName> false
$ adb shell am get-inactive <packageName>
觀察喚醒後的應用行為。確保應用從待機模式中正常恢復。 特別地,您應檢查應用的通知和後臺作業是否按預期繼續執行

三、ANDROID 7.0

1.行為變更

 Android 7.0 包括旨在延長裝置電池壽命和減少 RAM 使用的系統行為變更。這些變更可能會影響您的應用訪問系統資源,以及您的應用通過特定隱式 intent 與其他應用互動的方式。

1.低電耗模式

Android 6.0(API 級別 23)引入了低電耗模式,當用戶裝置未插接電源、處於靜止狀態且螢幕關閉時,該模式會推遲 CPU 和網路活動,從而延長電池壽命。而 Android 7.0 則通過在裝置未插接電源且螢幕關閉狀態下、但不一定要處於靜止狀態(例如使用者外出時把手持式裝置裝在口袋裡)時應用部分 CPU 和網路限制,進一步增強了低電耗模式。


2. Project Svelte:後臺優化

Android 7.0 移除了三項隱式廣播,以幫助優化記憶體使用和電量消耗。此項變更很有必要,因為隱式廣播會在後臺頻繁啟動已註冊偵聽這些廣播的應用。刪除這些廣播可以顯著提升裝置效能和使用者體驗。

移動裝置會經歷頻繁的連線變更,例如在 WLAN 和移動資料之間切換時。目前,可以通過在應用清單中註冊一個接收器來偵聽隱式 CONNECTIVITY_ACTION 廣播,讓應用能夠監控這些變更。由於很多應用會註冊接收此廣播,因此單次網路切換即會導致所有應用被喚醒並同時處理此廣播。

同理,在之前版本的 Android 中,應用可以註冊接收來自其他應用(例如相機)的隱式 ACTION_NEW_PICTURE 和 ACTION_NEW_VIDEO 廣播。當用戶使用相機應用拍攝照片時,這些應用即會被喚醒以處理廣播。

為緩解這些問題,Android 7.0 應用了以下優化措施:

面向 Android 7.0 開發的應用不會收到 CONNECTIVITY_ACTION 廣播,即使它們已有清單條目來請求接受這些事件的通知。在前臺執行的應用如果使用 BroadcastReceiver 請求接收通知,則仍可以在主執行緒中偵聽 CONNECTIVITY_CHANGE。
應用無法傳送或接收 ACTION_NEW_PICTURE 或 ACTION_NEW_VIDEO 廣播。此項優化會影響所有應用,而不僅僅是面向 Android 7.0 的應用。
如果您的應用使用任何 intent,您仍需要儘快移除它們的依賴關係,以正確適配 Android 7.0 裝置。Android 框架提供多個解決方案來緩解對這些隱式廣播的需求。例如,JobScheduler API 提供了一個穩健可靠的機制來安排滿足指定條件(例如連入無限流量網路)時所執行的網路操作。您甚至可以使用 JobScheduler 來適應內容提供程式變化。

如需瞭解有關 Android N 中後臺優化以及如何改寫應用的詳細資訊,請參閱後臺優化。

3.  許可權更改

Android 7.0 做了一些許可權更改,這些更改可能會影響您的應用。

系統許可權更改

為了提高私有檔案的安全性,面向 Android 7.0 或更高版本的應用私有目錄被限制訪問 (0700)。此設定可防止私有檔案的元資料洩漏,如它們的大小或存在性。此許可權更改有多重副作用:

私有檔案的檔案許可權不應再由所有者放寬,為使用 MODE_WORLD_READABLE 和/或 MODE_WORLD_WRITEABLE 而進行的此類嘗試將觸發 SecurityException。
注:迄今為止,這種限制尚不能完全執行。應用仍可能使用原生 API 或 File API 來修改它們的私有目錄許可權。但是,我們強烈反對放寬私有目錄的許可權。
傳遞軟體包網域外的 file:// URI 可能給接收器留下無法訪問的路徑。因此,嘗試傳遞 file:// URI 會觸發 FileUriExposedException。分享私有檔案內容的推薦方法是使用 FileProvider。
DownloadManager 不再按檔名分享私人儲存的檔案。
舊版應用在訪問 COLUMN_LOCAL_FILENAME 時可能出現無法訪問的路徑。
面向 Android 7.0 或更高版本的應用在嘗試訪問 COLUMN_LOCAL_FILENAME 時會觸發 SecurityException。
通過使用 DownloadManager.Request.setDestinationInExternalFilesDir() 或 DownloadManager.Request.setDestinationInExternalPublicDir() 將下載位置設定為公共位置的舊版應用仍可以訪問 COLUMN_LOCAL_FILENAME 中的路徑,但是我們強烈反對使用這種方法。對於由 DownloadManager 公開的檔案,首選的訪問方式是使用ContentResolver.openFileDescriptor()。


4.在應用間共享檔案
對於面向 Android 7.0 的應用,Android 框架執行的 StrictMode API 政策禁止在您的應用外部公開 file:// URI。如果一項包含檔案 URI 的 intent 離開您的應用,則應用出現故障,並出現 FileUriExposedException 異常。
要在應用間共享檔案,您應傳送一項 content:// URI,並授予 URI 臨時訪問許可權。進行此授權的最簡單方式是使用 FileProvider 類。如需瞭解有關許可權和共享檔案的詳細資訊,請參閱共享檔案。


5.螢幕縮放
Android 7.0 支援使用者設定顯示尺寸,以放大或縮小螢幕上的所有元素,從而提升裝置對視力不佳使用者的可訪問性。使用者無法將螢幕縮放至低於最小螢幕寬度 sw320dp,該寬度是 Nexus 4 的寬度,也是常規中等大小手機的寬度。

6.無障礙改進
為提高平臺對於視力不佳或視力受損使用者的易用性,Android 7.0 做出了一些更改。這些更改一般並不要求更改您的應用程式碼,不過您應仔細檢查並使用您的應用測試這些功能,以評估它們對使用者體驗的潛在影響.

7.NDK 應用連結至平臺庫
從 Android 7.0 開始,系統將阻止應用動態連結非公開 NDK 庫,這種庫可能會導致您的應用崩潰。此行為變更旨在為跨平臺更新和不同裝置提供統一的應用體驗。即使您的程式碼可能不會連結私有庫,但您的應用中的第三方靜態庫可能會這麼做。因此,所有開發者都應進行相應檢查,確保他們的應用不會在執行 Android 7.0 的裝置上崩潰。如果您的應用使用原生程式碼,則只能使用公開 NDK API。

8.Android for Work
Android 7.0 包含一些針對面向 Android for Work 的應用的變更,包括對證書安裝、密碼重置、二級使用者管理、裝置識別符號訪問許可權的變更。如果您是要針對 Android for Work 環境開發應用,則應仔細檢查這些變更並相應地修改您的應用
                          

四、Android 8.0

1.行為變更

Android 8.0 除了提供諸多新特性和功能外,還對系統和 API 行為做出了各種變更。本文重點介紹您應該瞭解並在開發應用時加以考慮的一些主要變更。

其中大部分變更會影響所有應用,而不論應用針對的是何種版本的 Android。不過,有幾項變更僅影響針對 Android 8.0 的應用。為清楚起見,本頁面分為兩個部分:針對所有 API 級別的應用和針對 Android 8.0 的應用。

針對所有 API 級別的應用

這些行為變更適用於 在 Android 8.0 平臺上執行的 所有應用,無論這些應用是針對哪個 API 級別構建。所有開發者都應檢視這些變更,並修改其應用以正確支援這些變更(如果適用)。

一.  後臺執行限制

Android 8.0 為提高電池續航時間而引入的變更之一是,當您的應用進入已快取狀態時,如果沒有活動的元件,系統將解除應用具有的所有喚醒鎖。

此外,為提高裝置效能,系統會限制未在前臺執行的應用的某些行為。具體而言:

現在,在後臺執行的應用對後臺服務的訪問受到限制。
應用無法使用其清單註冊大部分隱式廣播(即,並非專門針對此應用的廣播)。
預設情況下,這些限制僅適用於針對 O 的應用。不過,使用者可以從 Settings 螢幕為任意應用啟用這些限制,即使應用並不是以 O 為目標平臺。

1. Android 8.0 還對特定函式做出了以下變更:

如果針對 Android 8.0 的應用嘗試在不允許其建立後臺服務的情況下使用 startService() 函式,則該函式將引發一個 IllegalStateException。
新的 Context.startForegroundService() 函式將啟動一個前臺服務。現在,即使應用在後臺執行,系統也允許其呼叫 Context.startForegroundService()。不過,應用必須在建立服務後的五秒內呼叫該服務的 startForeground() 函式。
如需瞭解詳細資訊,請參閱後臺執行限制。

多個 Android 應用和服務可以同時執行。 例如,使用者可以在一個視窗中玩遊戲,同時在另一個視窗中瀏覽網頁,並使用第三個應用播放音樂。

同時執行的應用越多,對系統造成的負擔越大。 如果還有應用或服務在後臺執行,這會對系統造成更大負擔,進而可能導致使用者體驗下降;例如,音樂應用可能會突然關閉。


(1)在很多情況下,您的應用都可以使用 JobScheduler 作業替換後臺服務。 例如,CoolPhotoApp 需要檢查使用者是否已經從朋友那裡收到共享的照片,即使該應用未在前臺執行。

(2)在 Android 8.0 之前,建立前臺服務的方式通常是先建立一個後臺服務,然後將該服務推到前臺。

Android 8.0 有一項複雜功能;系統不允許後臺應用建立後臺服務。 因此,Android 8.0 引入了一種全新的方法,即 Context.startForegroundService(),以在前臺啟動新服務。

在系統建立服務後,應用有五秒的時間來呼叫該服務的 startForeground() 方法以顯示新服務的使用者可見通知。

如果應用在此時間限制內未呼叫 startForeground(),則系統將停止服務並宣告此應用為 ANR。

2.廣播限制

如果應用註冊為接收廣播,則在每次傳送廣播時,應用的接收器都會消耗資源。 如果多個應用註冊為接收基於系統事件的廣播,這會引發問題;觸發廣播的系統事件會導致所有應用快速地連續消耗資源,從而降低使用者體驗。

為了緩解這一問題,Android 7.0(API 級別 25)對廣播施加了一些限制,如後臺優化中所述。

Android 8.0 讓這些限制更為嚴格。

針對 Android 8.0 的應用無法繼續在其清單中為隱式廣播註冊廣播接收器。 隱式廣播是一種不專門針對該應用的廣播。 例如,ACTION_PACKAGE_REPLACED 就是一種隱式廣播,因為它將傳送到註冊的所有偵聽器,讓後者知道裝置上的某些軟體包已被替換。

不過,ACTION_MY_PACKAGE_REPLACED 不是隱式廣播,因為不管已為該廣播註冊偵聽器的其他應用有多少,它都會只發送到軟體包已被替換的應用。
應用可以繼續在它們的清單中註冊顯式廣播。
應用可以在執行時使用 Context.registerReceiver() 為任意廣播(不管是隱式還是顯式)註冊接收器。
需要簽名許可權的廣播不受此限制所限,因為這些廣播只會傳送到使用相同證書籤名的應用,而不是傳送到裝置上的所有應用。
在許多情況下,之前註冊隱式廣播的應用使用 JobScheduler 作業可以獲得類似的功能。

例如,一款社交照片應用可能需要不時地執行資料清理,並且傾向於在裝置連線到充電器時執行此操作。

之前,應用已經在清單中為 ACTION_POWER_CONNECTED 註冊了一個接收器;當應用接收到該廣播時,它會檢查清理是否必要。 為了遷移到 Android 8.0,應用將該接收器從其清單中移除。

應用將清理作業安排在裝置處於空閒狀態和充電時執行。

注:很多隱式廣播當前均已不受此限制所限。 應用可以繼續在其清單中為這些廣播註冊接收器,不管應用針對哪個 API 級別。 有關已豁免廣播的列表,請參閱隱式廣播例外。

3.遷移指南

預設情況下,這些更改僅影響針對 O 的應用。 不過,使用者可以從 Settings 螢幕為任意應用啟用這些限制,即使應用並不是以 O 為目標平臺。

您可能需要更新應用,使其符合新限制。

瞭解您的應用如何使用服務。 如果您的應用依賴某些在它處於空閒時於後臺執行的服務,您需要替換這些服務。

可能的解決方法包括:

如果處於後臺時您的應用需要建立一個前臺服務,請使用新的 NotificationManager.startServiceInForeground()

方法,而不是建立一個後臺服務,然後嘗試將其推到前臺。
如果服務容易被使用者注意,請將其設為前臺服務。 例如,播放音訊的服務始終應為前臺服務。

使用 NotificationManager.startServiceInForeground()

而不是 startService() 建立服務。
尋找一種使用計劃作業實現服務功能的方式。 如果服務未在執行容易立即被使用者注意到的操作,一般情況下,您都能夠使用計劃作業。
發生網路事件時,請使用 FCM 選擇性地喚醒您的應用,而不是在後臺輪詢。
在應用正常處於前臺之前,請推遲後臺工作。
檢查在您應用的清單中定義的廣播接收器。 如果您的清單為顯式廣播聲明瞭接收器,您必須予以替換。 可能的解決方法包括:

通過呼叫 Context.registerReceiver() 而不是在清單中宣告接收器的方式在執行時建立接收器。
使用計劃作業檢查條件是否會觸發隱式廣播。

4. Android 後臺位置限制
為降低功耗,無論應用的目標 SDK 版本為何,Android 8.0 都會對後臺應用檢索使用者當前位置的頻率進行限制。

為節約電池電量、保持良好的使用者體驗和確保系統健康執行,在執行 Android 8.0 的裝置上使用後臺應用時,降低了後臺應用接收位置更新的頻率。此行為變更會影響包括 Google Play 服務在內的所有接收位置更新的應用。

為降低功耗,無論應用的目標 SDK 版本為何,Android 8.0 都會對後臺應用檢索使用者當前位置的頻率進行限制。

(1)系統會對前臺應用和後臺應用進行區分。應用滿足以下任一條件即視為前臺應用:

它具有可見的 Activity,無論 Activity 處於啟動還是暫停狀態。
它具有前臺服務。
另一個前臺應用通過繫結到應用的其中一個服務或使用應用的其中一個內容提供程式與應用相連。
如果以上所有條件均不滿足,應用即視為後臺應用。

(2)優化應用的位置行為

考慮在您的應用接收位置更新不頻繁的情況下其後臺執行用例是否根本無法成功。如果屬於這種情況,您可以通過執行下列操作之一提高位置更新的檢索頻率:

將您的應用轉至前臺。
使用應用中的某個前臺服務。啟用此服務時,您的應用必須在通知區顯示一個持續性的通知。
使用 Geofencing API 的元素(例如 GeofencingApi 介面),這些元素針對最大限度減少耗電進行了專門優化。
使用被動位置偵聽器,它可以在後臺應用加快位置請求頻率時提高位置更新的接收頻率。
注:如果您的應用需要訪問的位置歷史記錄包含時間頻繁更新,請使用批處理版本的 Fused Location Provider API 元素,例如 FusedLocationProviderApi 介面。當您的應用運行於後臺時,此 API 會以高於非批處理版本 API 的頻率接收使用者的位置。但切記,您的應用批量接收更新的頻率仍僅為每小時幾次。

(3)受影響的 API

對後臺應用位置檢索行為的更改影響下列 API:

Fused Location Provider (FLP)
如果您的應用執行在後臺,位置系統服務只會根據 Android 8.0 行為變更中定義的間隔,按每小時幾次的頻率為其計算新位置。即使您的應用請求進行更頻繁的位置更新,也仍是如此。
如果您的應用執行在前臺,與 Android 7.1.1(API 級別 25)相比,在位置取樣率上不會有任何變化。
Geofencing
後臺應用可以高於接收 Fused Location Provider 更新的頻率接收地理圍欄轉換事件。
地理圍欄事件的平均響應時間是大約每兩分鐘一次。
GNSS Measurements 和 GNSS Navigation Messages
當您的應用位於後臺時,註冊用於接收 GnssMeasurement 和 GnssNavigationMessage 輸出的回撥會停止執行。
Location Manager
提供給後臺應用的位置更新只會根據 Android 8.0 行為變更中定義的間隔,按每小時幾次的頻率提供。

注:如果執行您的應用的裝置安裝了 Google Play 服務,強烈建議您改用 Fused Location Provider (FLP)。
WLAN 管理器
startScan() 方法對後臺應用執行完整掃描的頻率僅為每小時數次。如果不久之後後臺應用再次呼叫此方法, WifiManager 類將提供上次掃描所快取的結果。


2. Android 8.0 API變更


1. 通知

在 Android 8.0 中,我們已重新設計通知,以便為管理通知行為和設定提供更輕鬆和更統一的方式。這些變更包括:

Android 8.0 中的通知長按選單。
圖 1. 使用者可以長按應用啟動器圖示以檢視 Android 8.0 中的通知。

通知渠道:Android 8.0 引入了通知渠道,其允許您為要顯示的每種通知型別建立使用者可自定義的渠道。使用者介面將通知渠道稱之為通知類別。要了解如何實現通知渠道的資訊,請參閱通知渠道指南。
通知標誌:Android 8.0 引入了對在應用啟動器圖示上顯示通知標誌的支援。通知標誌可反映某個應用是否存在與其關聯、並且使用者尚未予以清除也未對其採取行動的通知。通知標誌也稱為通知點。要了解如何調整通知標誌,請參閱通知標誌指南。
休眠:使用者可以將通知置於休眠狀態,以便稍後重新顯示它。重新顯示時通知的重要程度與首次顯示時相同。應用可以移除或更新已休眠的通知,但更新休眠的通知並不會使其重新顯示。
通知超時:現在,使用 setTimeoutAfter() 建立通知時您可以設定超時。您可以使用此函式指定一個持續時間,超過該持續時間後,通知應取消。如果需要,您可以在指定的超時持續時間之前取消通知。
通知設定:當您使用 Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCESIntent 從通知建立指向應用通知設定的連結時,您可以呼叫 setSettingsText() 來設定要顯示的文字。此係統可以提供以下 Extra 資料和 Intent,用於過濾應用必須向用戶顯示的設定