Android 8.0 功能和 API
API 級別:27
Android 8.0 為用戶和開發(fā)者引入多種新功能。本文重點介紹面向開發(fā)者的新功能。
請務(wù)必查閱 Android 8.0 行為變更以了解平臺變更可能影響您的應(yīng)用的領(lǐng)域。
用戶體驗
通知
在 Android 8.0 中,我們已重新設(shè)計通知,以便為管理通知行為和設(shè)置提供更輕松和更統(tǒng)一的方式。這些變更包括:
用戶可以長按應(yīng)用啟動器圖標以查看 Android 8.0 中的通知。
- 通知渠道:Android 8.0 引入了通知渠道,其允許您為要顯示的每種通知類型創(chuàng)建用戶可自定義的渠道。用戶界面將通知渠道稱之為通知類別。要了解如何實現(xiàn)通知渠道的信息,請參閱通知渠道指南。
- 通知標志:Android 8.0 引入了對在應(yīng)用啟動器圖標上顯示通知標志的支持。通知標志可反映某個應(yīng)用是否存在與其關(guān)聯(lián)、并且用戶尚未予以清除也未對其采取行動的通知。通知標志也稱為通知點。要了解如何調(diào)整通知標志,請參閱通知標志指南。
- 休眠:用戶可以將通知置于休眠狀態(tài),以便稍后重新顯示它。重新顯示時通知的重要程度與首次顯示時相同。應(yīng)用可以移除或更新已休眠的通知,但更新休眠的通知并不會使其重新顯示。
- 通知超時:現(xiàn)在,使用
[setTimeoutAfter()](https://developer.android.com/reference/android/app/Notification.Builder#setTimeoutAfter(long))創(chuàng)建通知時您可以設(shè)置超時。您可以使用此函數(shù)指定一個持續(xù)時間,超過該持續(xù)時間后,通知應(yīng)取消。如果需要,您可以在指定的超時持續(xù)時間之前取消通知。 - 通知設(shè)置:當(dāng)您使用
[Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES](https://developer.android.com/reference/android/app/Notification#INTENT_CATEGORY_NOTIFICATION_PREFERENCES)Intent 從通知創(chuàng)建指向應(yīng)用通知設(shè)置的鏈接時,您可以調(diào)用setSettingsText()來設(shè)置要顯示的文本。此系統(tǒng)可以提供以下 Extra 數(shù)據(jù)和 Intent,用于過濾應(yīng)用必須向用戶顯示的設(shè)置:EXTRA_CHANNEL_ID、NOTIFICATION_TAG和NOTIFICATION_ID。 - 通知清除:系統(tǒng)現(xiàn)在可區(qū)分通知是由用戶清除,還是由應(yīng)用移除。要查看清除通知的方式,您應(yīng)實現(xiàn)
[NotificationListenerService](https://developer.android.com/reference/android/service/notification/NotificationListenerService)類的新[onNotificationRemoved()](https://developer.android.com/reference/android/service/notification/NotificationListenerService#onNotificationRemoved(android.service.notification.StatusBarNotification,%20android.service.notification.NotificationListenerService.RankingMap,%20int))函數(shù)。 - 背景顏色:您現(xiàn)在可以設(shè)置和啟用通知的背景顏色。只能在用戶必須一眼就能看到的持續(xù)任務(wù)的通知中使用此功能。例如,您可以為與駕車路線或正在進行的通話有關(guān)的通知設(shè)置背景顏色。您還可以使用
[Notification.Builder.setColor()](https://developer.android.com/reference/android/app/Notification.Builder#setColor(int))設(shè)置所需的背景顏色。這樣做將允許您使用[Notification.Builder.setColorized()](https://developer.android.com/reference/android/app/Notification.Builder#setColorized(boolean))啟用通知的背景顏色設(shè)置。 - 消息樣式:現(xiàn)在,使用
[MessagingStyle](https://developer.android.com/reference/android/app/Notification.MessagingStyle)類的通知可在其折疊形式中顯示更多內(nèi)容。對于與消息有關(guān)的通知,您應(yīng)使用[MessagingStyle](https://developer.android.com/reference/android/app/Notification.MessagingStyle)類。您還可以使用新的[addHistoricMessage()](https://developer.android.com/reference/android/app/Notification.MessagingStyle#addHistoricMessage(android.app.Notification.MessagingStyle.Message))函數(shù),通過向與消息相關(guān)的通知添加歷史消息為會話提供上下文。
自動填充框架
帳號創(chuàng)建、登錄和信用卡交易需要時間并且容易出錯。在使用要求執(zhí)行此類重復(fù)性任務(wù)的應(yīng)用時,用戶很容易遭受挫折。
Android 8.0 通過引入自動填充框架,簡化了登錄和信用卡表單之類表單的填寫工作。在用戶選擇接受自動填充之后,新老應(yīng)用都可使用自動填充框架。
您可以采取某些措施,優(yōu)化您的應(yīng)用使用此框架的方式。如需了解詳細信息,請參閱自動填充框架概覽。
畫中畫模式
Android 8.0 允許以畫中畫 (PIP) 模式啟動操作組件。PIP 是一種特殊的多窗口模式,最常用于視頻播放。目前,PIP 模式可用于 Android TV,而 Android 8.0 則讓該功能可進一步用于其他 Android 設(shè)備。
當(dāng)某個 Activity 處于 PIP 模式時,它會處于暫停狀態(tài),但仍應(yīng)繼續(xù)顯示內(nèi)容。因此,您應(yīng)確保您的應(yīng)用在 [onPause()](https://developer.android.com/reference/android/app/Activity#onPause()) 處理程序中進行處理時不會暫停播放。相反,您應(yīng)在 [onStop()](https://developer.android.com/reference/android/app/Activity#onStop()) 中暫停播放視頻,并在 [onStart()](https://developer.android.com/reference/android/app/Activity#onStart()) 中繼續(xù)播放。如需了解詳細信息,請參閱多窗口生命周期。
要指定您的 Activity 可以使用 PIP 模式,請在清單中將 android:supportsPictureInPicture 設(shè)置為 true。(從 Android 8.0 開始,如果您打算在 Android TV 或其他 Android 設(shè)備上支持 PIP 模式,則無需將 android:resizeableActivity 設(shè)置為 true;只有在您的 Activity 支持其他多窗口模式時,才需要設(shè)置 android:resizeableActivity。)
API 變更
Android 8.0 引入一種新的對象 [PictureInPictureParams](https://developer.android.com/reference/android/app/PictureInPictureParams),您可以將該對象傳遞給 PIP 函數(shù)來指定某個 Activity 在其處于 PIP 模式時的行為。此對象還指定了各種屬性,例如操作組件的首選縱橫比。
現(xiàn)在,在添加畫中畫中介紹的現(xiàn)有 PIP 函數(shù)可用于所有 Android 設(shè)備,而不僅限于 Android TV。此外,Android 8.0 還提供以下函數(shù)來支持 PIP 模式:
-
[Activity.enterPictureInPictureMode(PictureInPictureParams args)](https://developer.android.com/reference/android/app/Activity#enterPictureInPictureMode(android.app.PictureInPictureParams)):將操作組件置于畫中畫模式。操作組件的縱橫比和其他配置設(shè)置均由args指定。如果args中的任何字段為空,系統(tǒng)將使用您上次調(diào)用[Activity.setPictureInPictureParams()](https://developer.android.com/reference/android/app/Activity#setPictureInPictureParams(android.app.PictureInPictureParams))時所設(shè)置的值。指定的操作組件被置于屏幕的一角,屏幕剩余部分則被屏幕顯示的上一個操作組件填滿。進入 PIP 模式的 Activity 將進入暫停狀態(tài),但仍保持已啟動狀態(tài)。如果用戶點按此 PIP 操作組件,系統(tǒng)將顯示一個菜單供用戶操作,而在操作組件處于 PIP 狀態(tài)期間,不會理會任何觸摸事件。
[Activity.setPictureInPictureParams()](https://developer.android.com/reference/android/app/Activity#setPictureInPictureParams(android.app.PictureInPictureParams)):更新操作組件的 PIP 配置設(shè)置。如果操作組件目前處于 PIP 模式,則會更新此設(shè)置;如果操作組件的縱橫比發(fā)生變化,這非常有用。如果操作組件不處于 PIP 模式,則會使用這些配置設(shè)置,而不會考慮您調(diào)用的enterPictureInPictureMode()函數(shù)。
可下載字體
Android 8.0 和 Android 支持庫 26 允許您從提供程序應(yīng)用請求字體,而無需將字體綁定到 APK 中或讓 APK 下載字體。此功能可減小 APK 大小,提高應(yīng)用安裝成功率,使多個應(yīng)用可以共享同一種字體。
如需了解有關(guān)下載字體的詳細信息,請參閱 可下載字體。
XML 中的字體
Android 8.0 推出一項新功能,即 XML 中的字體,允許您使用字體作為資源。這意味著,不再需要以資產(chǎn)的形式捆綁字體。字體在 R 文件中編譯,并且作為一種資源,可自動用于系統(tǒng)。然后,您可以利用一種新的資源類型 font 來訪問這些字體。
在運行 API 版本 14 及更高版本的設(shè)備中,支持庫 26 對此功能提供完全支持。
如需了解有關(guān)以資源形式使用字體以及檢索系統(tǒng)字體有關(guān)的詳細信息,請參閱 XML 中的字體。
自動調(diào)整 TextView 的大小
Android 8.0 允許您根據(jù) TextView 的大小自動設(shè)置文本展開或收縮的大小。這意味著,在不同屏幕上優(yōu)化文本大小或者優(yōu)化包含動態(tài)內(nèi)容的文本大小比以往簡單多了。如需了解有關(guān)如何在 Android 8.0 中自動調(diào)整 TextView 的大小的詳細信息,請參閱自動調(diào)整 TextView 的大小。
自適應(yīng)圖標
Android 8.0 引入自適應(yīng)啟動器圖標。自適應(yīng)圖標支持視覺效果,可在不同設(shè)備型號上顯示為各種不同的形狀。要了解如何創(chuàng)建自適應(yīng)圖標,請參閱自適應(yīng)圖標預(yù)覽功能指南。
顏色管理
圖像應(yīng)用的 Android 開發(fā)者現(xiàn)在可以利用支持廣色域彩色顯示的新設(shè)備。要顯示廣色域圖像,應(yīng)用需要在其清單(每個操作組件)中啟用一個標志,并加載具有嵌入的廣域彩色配置文件(AdobeRGB、Pro Photo RGB、DCI-P3 等)的位圖。
WebView API
Android 8.0 提供多種 API,幫助您管理在應(yīng)用中顯示網(wǎng)頁內(nèi)容的 [WebView](https://developer.android.com/reference/android/webkit/WebView) 對象。這些 API 可增強應(yīng)用的穩(wěn)定性和安全性,它們包括:
- Version API
- Google SafeBrowsing API
- Termination Handle API
- Renderer Importance API
要詳細了解如何這些 API,請參閱管理 WebView。
固定快捷方式和小部件
Android 8.0 引入了快捷方式和微件的應(yīng)用內(nèi)固定功能。在您的應(yīng)用中,您可以根據(jù)用戶權(quán)限為支持的啟動器創(chuàng)建固定的快捷方式和小部件。
如需了解詳細信息,請參閱固定快捷方式和微件預(yù)覽功能指南。
最大屏幕縱橫比
以 Android 7.1(API 級別 25)或更低版本為目標平臺的應(yīng)用默認的最大屏幕縱橫比為 1.86。針對 Android 8.0 或更高版本的應(yīng)用沒有默認的最大縱橫比。如果您的應(yīng)用需要設(shè)置最大縱橫比,請使用定義您的操作組件的清單文件中的 maxAspectRatio 屬性。
多顯示器支持
從 Android 8.0 開始,此平臺為多顯示器提供增強的支持。如果 Activity 支持多窗口模式,并且在具有多顯示器的設(shè)備上運行,則用戶可以將 Activity 從一個顯示器移動到另一個顯示器。當(dāng)應(yīng)用啟動 Activity 時,此應(yīng)用可指定 Activity 應(yīng)在哪個顯示器上運行。
注:如果 Activity 支持多窗口模式,則 Android 8.0 將為該 Activity 自動啟用多顯示器支持。您應(yīng)測試您的應(yīng)用,確保它在多顯示器環(huán)境下可正常運行。
每次只有一個 Activity 可以處于繼續(xù)狀態(tài),即使此應(yīng)用具有多個顯示器。具有焦點的 Activity 將處于繼續(xù)狀態(tài),所有其他可見的 Activity 均暫停,但不會停止。如需了解有關(guān)當(dāng)多個 Activity 可見時活動生命周期的詳細信息,請參閱多窗口生命周期。
當(dāng)用戶將 Activity 從一個顯示器移動到另一個顯示器時,系統(tǒng)將調(diào)整 Activity 大小,并根據(jù)需要發(fā)起運行時變更。您的 Activity 可以自行處理配置變更,或允許系統(tǒng)銷毀包含該 Activity 的進程,并以新的尺寸重新創(chuàng)建它。如需了解詳細信息,請參閱處理配置變更。
[ActivityOptions](https://developer.android.com/reference/android/app/ActivityOptions) 提供兩個新函數(shù)以支持多個顯示器:
[setLaunchDisplayId()](https://developer.android.com/reference/android/app/ActivityOptions#setLaunchDisplayId(int))
指定 Activity 在啟動后應(yīng)顯示在哪個顯示器上。
[getLaunchDisplayId()](https://developer.android.com/reference/android/app/ActivityOptions#getLaunchDisplayId())
返回操作組件的當(dāng)前啟動顯示器。
對 adb shell 進行了擴展,以支持多個顯示器。shell start 命令現(xiàn)在可用于啟動操作組件,并指定操作組件的目標顯示器:
adb shell start <activity_name> --display <display_id>
統(tǒng)一的布局外邊距和內(nèi)邊距
Android 8.0 讓您可以更輕松地指定 [View](https://developer.android.com/reference/android/view/View) 元素的對邊使用相同外邊距和內(nèi)邊距的情形。具體來說,您現(xiàn)在可以在布局 XML 文件中使用以下屬性:
-
layout_marginVertical,同時定義layout_marginTop和layout_marginBottom。 -
layout_marginHorizontal,同時定義layout_marginLeft和layout_marginRight。 -
paddingVertical,同時定義paddingTop和paddingBottom。 -
paddingHorizontal,同時定義paddingLeft和paddingRight。
注:如果您自定義應(yīng)用邏輯以支持不同語言和文化(包括文本方向),請記住,這些屬性不會影響 layout_marginStart、layout_marginEnd、paddingStart 或 paddingEnd 的值。您可以自行設(shè)置這些值和新的垂直與水平布局屬性來創(chuàng)建取決于文本方向的布局行為。
指針捕獲
某些應(yīng)用(例如游戲、遠程桌面和虛擬化客戶端)將大大受益于鼠標指針控制。指針捕獲是 Android 8.0 中的一項新功能,可以通過將所有鼠標事件傳遞到您的應(yīng)用中焦點視圖的方式提供此類控制。
從 Android 8.0 開始,您的應(yīng)用中的 [View](https://developer.android.com/reference/android/view/View) 可以請求指針捕獲并定義一個偵聽器來處理捕獲的指針事件。鼠標指針在此模式下將隱藏。如果不再需要鼠標信息,該視圖可以釋放指針捕獲。系統(tǒng)也可以在視圖丟失焦點時(例如,當(dāng)用戶打開另一個應(yīng)用時)釋放指針捕獲。
如需了解有關(guān)如何在您的應(yīng)用中使用此功能的信息,請參閱指針捕獲。
應(yīng)用類別
在適當(dāng)?shù)那闆r下,Android 8.0 允許每個應(yīng)用聲明其所屬的類別。這些類別用于將應(yīng)用呈現(xiàn)給用戶的用途或功能類似的應(yīng)用歸類在一起,例如按流量消耗、電池消耗和存儲消耗將應(yīng)用歸類。您可以在 <application> 清單標記中設(shè)置 android:appCategory 屬性,定義應(yīng)用的類別。
Android TV 啟動器
Android 8.0 添加了一種以內(nèi)容為中心的全新 Android TV 主屏幕體驗,支持 Android TV 模擬器和 Nexus Player Android 8.0 設(shè)備映像。新的主屏幕在對應(yīng)于頻道的行中組織視頻內(nèi)容,這些頻道在系統(tǒng)上通過應(yīng)用填充各個節(jié)目。應(yīng)用可以發(fā)布多個頻道,用戶可以配置他們希望在主屏幕上看到哪些頻道。Android TV 也包含一個 Watch Next 行,此行根據(jù)用戶的觀看習(xí)慣從應(yīng)用填充節(jié)目。應(yīng)用也可以提供視頻預(yù)覽,這些預(yù)覽會在用戶聚焦到節(jié)目時自動播放。用于填充頻道和節(jié)目的 API 屬于 TvProvider API,這些 API 以 Android 支持庫模塊的形式隨 Android 8.0 分發(fā)。
AnimatorSet
從 Android 8.0 開始,[AnimatorSet](https://developer.android.com/reference/android/animation/AnimatorSet) API 現(xiàn)在支持尋道和倒播功能。尋道功能允許您將動畫的位置設(shè)置為指定的時間點處。如果您的應(yīng)用包含可撤消的操作的動畫,倒播功能會很有用?,F(xiàn)在,您不必定義兩組獨立的動畫,而只需反向播放同一組動畫。
輸入和導(dǎo)航
鍵盤導(dǎo)航鍵區(qū)
如果您的應(yīng)用中,某個操作組件使用一種復(fù)雜的視圖層次結(jié)構(gòu)(如圖 2 所示),可考慮將多組界面元素組成一個鍵區(qū),簡化鍵盤導(dǎo)航這些元素的操作。用戶可以在 Chromebook 設(shè)備上按 Meta+Tab 或 Search+Tab,在不同鍵區(qū)之間導(dǎo)航。鍵區(qū)的一些范例包括:側(cè)面板、導(dǎo)航欄、主內(nèi)容區(qū)域和可能包含多個子元素的元素。
包含 5 個鍵區(qū)的操作組件
要將一個 [View](https://developer.android.com/reference/android/view/View) 或 [ViewGroup](https://developer.android.com/reference/android/view/ViewGroup) 元素設(shè)置為一個鍵區(qū),請在元素的布局 XML 文件中將 android:keyboardNavigationCluster 屬性設(shè)置為 true,或者將 true 傳遞至應(yīng)用界面邏輯中的 [setKeyboardNavigationCluster()](https://developer.android.com/reference/android/view/View#setKeyboardNavigationCluster(boolean))。
注:鍵區(qū)不能嵌套,不過,非嵌套鍵區(qū)可以顯示在層次結(jié)構(gòu)的不同層級。如果您嘗試嵌套鍵區(qū),框架僅會將最頂層的 [ViewGroup](https://developer.android.com/reference/android/view/ViewGroup) 元素視為鍵區(qū)。
在具有觸摸屏的設(shè)備中,您可以將某個鍵區(qū)指定的 [ViewGroup](https://developer.android.com/reference/android/view/ViewGroup) 對象的 android:touchscreenBlocksFocus 元素設(shè)置為 true,僅允許從鍵區(qū)導(dǎo)航進入和離開此鍵區(qū)。如果您將此配置應(yīng)用于某個鍵區(qū),用戶將無法使用 Tab 鍵或箭頭鍵導(dǎo)航進入或離開此鍵區(qū),而是必須按鍵區(qū)導(dǎo)航鍵盤組合鍵。
視圖默認焦點
在 Android 8.0 中,您可以指定在(重新)創(chuàng)建的操作組件繼續(xù)運行并且用戶按下鍵盤導(dǎo)航鍵(例如 Tab 鍵)之后應(yīng)接收焦點的 [View](https://developer.android.com/reference/android/view/View)。要應(yīng)用“設(shè)為默認焦點”設(shè)置,請在包含界面元素的布局 XML 文件中將 [View](https://developer.android.com/reference/android/view/View) 元素的 android:focusedByDefault 屬性設(shè)置為 true,或者將 true 傳遞至應(yīng)用界面邏輯中的 [setFocusedByDefault()](https://developer.android.com/reference/android/view/View#setFocusedByDefault(boolean))。
系統(tǒng)
新的 StrictMode 檢測程序
Android 8.0 添加了三個新的 StrictMode 檢測程序,幫助識別應(yīng)用可能出現(xiàn)的錯誤:
-
[detectUnbufferedIo()](https://developer.android.com/reference/android/os/StrictMode.ThreadPolicy.Builder#detectUnbufferedIo())將檢測您的應(yīng)用何時讀取或?qū)懭胛淳彌_的數(shù)據(jù),這可能極大影響性能。 -
[detectContentUriWithoutPermission()](https://developer.android.com/reference/android/os/StrictMode.VmPolicy.Builder#detectContentUriWithoutPermission())將檢測您的應(yīng)用在其外部啟動 Activity 時何時意外忘記向其他應(yīng)用授予權(quán)限。 -
[detectUntaggedSockets()](https://developer.android.com/reference/android/os/StrictMode.VmPolicy.Builder#detectUntaggedSockets())將檢測您的應(yīng)用何時使用網(wǎng)絡(luò)流量,而不使用[setThreadStatsTag(int)](https://developer.android.com/reference/android/net/TrafficStats#setThreadStatsTag(int))將流量標記用于調(diào)試目的。
緩存數(shù)據(jù)
Android 8.0 優(yōu)化了緩存數(shù)據(jù)的導(dǎo)航和行為。現(xiàn)在,每個應(yīng)用均獲得一定的磁盤空間配額,用于存儲 [getCacheQuotaBytes(UUID)](https://developer.android.com/reference/android/os/storage/StorageManager#getCacheQuotaBytes(java.util.UUID)) 返回的緩存數(shù)據(jù)。
當(dāng)系統(tǒng)需要釋放磁盤空間時,將開始從超過配額最多的應(yīng)用中刪除緩存文件。因此,如果將您的緩存數(shù)據(jù)量始終保持低于配額的水平,則在必須清除系統(tǒng)中的某些文件時,您的緩存文件將能堅持到最后。系統(tǒng)在決定刪除您的應(yīng)用中的哪些緩存文件時,將首先考慮刪除最舊的文件(由修改時間確定)。
您還可以針對每個目錄啟用兩種新行為,以控制系統(tǒng)如何釋放緩存數(shù)據(jù):
-
StorageManager.setCacheBehaviorAtomic()可用于指示某個目錄及其所有內(nèi)容應(yīng)作為一個不可分割的整體進行刪除。 -
[setCacheBehaviorTombstone(File, boolean)](https://developer.android.com/reference/android/os/storage/StorageManager#setCacheBehaviorTombstone(java.io.File,%20boolean))可用于指示不應(yīng)刪除某個目錄內(nèi)的文件,而應(yīng)將它們截斷到 0 字節(jié)長度,使空文件保持完好。
最后,在需要為大文件分配磁盤空間時,可考慮使用新的 [allocateBytes(FileDescriptor, long)](https://developer.android.com/reference/android/os/storage/StorageManager#allocateBytes(java.io.FileDescriptor,%20long)) API,它將自動清除屬于其他應(yīng)用的緩存文件(根據(jù)需要),以滿足您的請求。在確定設(shè)備是否有足夠的磁盤空間保存您的新數(shù)據(jù)時,請調(diào)用 [getAllocatableBytes(UUID)](https://developer.android.com/reference/android/os/storage/StorageManager#getAllocatableBytes(java.util.UUID)) 而不要使用 [getUsableSpace()](https://developer.android.com/reference/java/io/File#getUsableSpace()),因為前者會考慮系統(tǒng)要為您清除的任何緩存數(shù)據(jù)。
內(nèi)容提供程序分頁
我們已更新內(nèi)容提供程序以支持加載大型數(shù)據(jù)集,每次加載一頁。例如,一個具有大量圖像的照片應(yīng)用可查詢要在頁面中顯示的數(shù)據(jù)的子集。內(nèi)容提供程序返回的每個結(jié)果頁面由一個 Cursor 對象表示??蛻舳撕吞峁┏绦虮仨殞崿F(xiàn)分頁才能利用此功能。
如需了解有關(guān)內(nèi)容提供程序變更的詳細信息,請參閱 [ContentProvider](https://developer.android.com/reference/android/content/ContentProvider) 和 [ContentProviderClient](https://developer.android.com/reference/android/content/ContentProviderClient)。
內(nèi)容刷新請求
現(xiàn)在,[ContentProvider](https://developer.android.com/reference/android/content/ContentProvider) 和 [ContentResolver](https://developer.android.com/reference/android/content/ContentResolver) 類均包含 refresh() 函數(shù),這樣,客戶端可以更輕松地知道所請求的信息是否為最新信息。
您可以擴展 [ContentProvider](https://developer.android.com/reference/android/content/ContentProvider) 以添加自定義的內(nèi)容刷新邏輯。請務(wù)必重寫 [refresh()](https://developer.android.com/reference/android/content/ContentProvider#refresh(android.net.Uri,%20android.os.Bundle,%20android.os.CancellationSignal)) 函數(shù),以返回 true,告知提供程序的客戶端您已嘗試自行刷新數(shù)據(jù)。
您的客戶端應(yīng)用可通過調(diào)用另一個函數(shù)(又稱 [refresh()](https://developer.android.com/reference/android/content/ContentResolver#refresh(android.net.Uri,%20android.os.Bundle,%20android.os.CancellationSignal))),顯式請求已刷新的內(nèi)容。在調(diào)用此函數(shù)時,傳入待刷新數(shù)據(jù)的 URI。
注:由于您可能通過網(wǎng)絡(luò)不斷請求數(shù)據(jù),您應(yīng)僅在有明顯跡象表明內(nèi)容確已過時時才從客戶端調(diào)用 [refresh()](https://developer.android.com/reference/android/content/ContentResolver#refresh(android.net.Uri,%20android.os.Bundle,%20android.os.CancellationSignal))。執(zhí)行此類內(nèi)容刷新最常見的原因是響應(yīng)滑動刷新手勢,該手勢顯式請求當(dāng)前界面顯示最新內(nèi)容。
JobScheduler 改進
Android 8.0 引入了對 [JobScheduler](https://developer.android.com/reference/android/app/job/JobScheduler) 的多項改進。由于您通??梢允褂糜媱澴鳂I(yè)替代現(xiàn)在受限的后臺服務(wù)或隱式廣播接收器,這些改進可以讓您的應(yīng)用更輕松地符合新的后臺執(zhí)行限制。
[JobScheduler](https://developer.android.com/reference/android/app/job/JobScheduler) 的更新包括:
- 您現(xiàn)在可以將工作隊列與計劃作業(yè)關(guān)聯(lián)。要將一個工作項添加到作業(yè)的隊列中,請調(diào)用
JobScheduler.enqueue()。當(dāng)作業(yè)運行時,它可以將待定工作從隊列中剝離并進行處理。這種功能可以處理之前需要啟動后臺服務(wù)(尤其是實現(xiàn)[IntentService](https://developer.android.com/reference/android/app/IntentService)的服務(wù))的許多用例。 - 您現(xiàn)在可以通過調(diào)用
JobInfo.Builder.setClipData()的方式將[ClipData](https://developer.android.com/reference/android/content/ClipData)與作業(yè)關(guān)聯(lián)。利用此選項,您可以將 URI 權(quán)限授予與作業(yè)關(guān)聯(lián),類似于這些權(quán)限傳遞到[Context.startService()](https://developer.android.com/reference/android/content/Context#startService(android.content.Intent))的方式。您也可以將 URI 權(quán)限授予用于工作隊列上的 intent。 - 計劃作業(yè)現(xiàn)在支持多個新的約束條件:
[`JobInfo.isRequireStorageNotLow()`](https://developer.android.com/reference/android/app/job/JobInfo#isRequireStorageNotLow())
如果設(shè)備的可用存儲空間非常低,作業(yè)將不會運行。
JobInfo.isRequireBatteryNotLow()
如果電池電量等于或低于臨界閾值,作業(yè)將不會運行;臨界閾值是指設(shè)備顯示 Low battery warning 系統(tǒng)對話框的電量。
[`NETWORK_TYPE_METERED`](https://developer.android.com/reference/android/app/job/JobInfo#NETWORK_TYPE_METERED)
作業(yè)需要一個按流量計費的網(wǎng)絡(luò)連接,比如大多數(shù)移動數(shù)據(jù)網(wǎng)絡(luò)數(shù)據(jù)套餐。</dd>
自定義數(shù)據(jù)存儲
Android 8.0 允許您為首選項提供自定義數(shù)據(jù)存儲,如果您的應(yīng)用將首選項存儲在云或本地數(shù)據(jù)庫中,或者如果首選項特定于某個設(shè)備,此功能會非常有用。如需了解有關(guān)實現(xiàn)數(shù)據(jù)存儲的詳細信息,請參閱自定義數(shù)據(jù)存儲。
findViewById() 簽名變更
現(xiàn)在,findViewById() 函數(shù)的全部實例均返回 <T extends View> T,而不是 View。此變更會帶來以下影響:
- 例如,如果
someMethod(View)和someMethod(TextView)均接受調(diào)用findViewById()的結(jié)果,這可能導(dǎo)致現(xiàn)有代碼的返回類型不確定。 - 在使用 Java 8 源語言時,這需要在返回類型不受限制時(例如,
assertNotNull(findViewById(...)).someViewMethod()))顯式轉(zhuǎn)換為View。 - 重寫非最終的
findViewById()函數(shù)(例如,Activity.findViewById())將需要更新其返回類型。
媒體增強功能
VolumeShaper
有一個新的 VolumeShaper 類。您可以用它來執(zhí)行簡短的自動音量轉(zhuǎn)換,例如淡入、淡出和交叉淡入淡出。
音頻焦點增強功能
音頻應(yīng)用通過請求和舍棄音頻焦點的方式在設(shè)備上共享音頻輸出。應(yīng)用通過啟動或停止播放或者閃避音量的方式處理處于聚焦?fàn)顟B(tài)的變更。有一個新的 AudioFocusRequest 類。對于此類,應(yīng)用在處理音頻焦點變化時會使用新功能:自動閃避和延遲聚焦。
媒體指標
新的 getMetrics() 函數(shù)將返回一個包含配置和性能信息的 [PersistableBundle](https://developer.android.com/reference/android/os/PersistableBundle) 對象,用一個包含屬性和值的地圖表示。為以下媒體類定義 getMetrics() 函數(shù):
[MediaPlayer.getMetrics()](https://developer.android.com/reference/android/media/MediaPlayer#getMetrics())[MediaRecorder.getMetrics()](https://developer.android.com/reference/android/media/MediaRecorder#getMetrics())[MediaCodec.getMetrics()](https://developer.android.com/reference/android/media/MediaCodec#getMetrics())[MediaExtractor.getMetrics()](https://developer.android.com/reference/android/media/MediaExtractor#getMetrics())
為每個實例單獨收集指標,并持續(xù)到實例的生命周期結(jié)束為止。如果沒有可用的指標,則此函數(shù)將返回 null。返回的實際指標取決于類。
MediaPlayer
Android 8.0 為 MediaPlayer 類添加了多種新函數(shù)。這些函數(shù)可以從多個方面增強您的應(yīng)用處理媒體播放的能力:
- 在搜索幀時進行精細控制。
- 播放受數(shù)字版權(quán)管理保護的材料的功能。
MediaPlayer 現(xiàn)在支持采樣級加密。
音頻錄制器
- 音頻錄制器現(xiàn)在支持對流式傳輸有用的 MPEG2_TS 格式:
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS);
請參閱 `[MediaRecorder.OutputFormat](https://developer.android.com/reference/android/media/MediaRecorder.OutputFormat)`
-
[MediaMuxer](https://developer.android.com/reference/android/media/MediaMuxer)現(xiàn)在可以處理任意數(shù)量的音頻和視頻流,而不再僅限于一個音頻曲目和/或一個視頻曲目。使用[addTrack()](https://developer.android.com/reference/android/media/MediaMuxer#addTrack(android.media.MediaFormat))可混錄所需的任意數(shù)量的曲目。 -
[MediaMuxer](https://developer.android.com/reference/android/media/MediaMuxer)還可以添加一個或多個包含用戶定義的每幀信息的元數(shù)據(jù)曲目。元數(shù)據(jù)的格式由您的應(yīng)用定義。僅對 MP4 容器支持元數(shù)據(jù)曲目。
元數(shù)據(jù)可以用于離線處理。例如,傳感器的陀螺儀信號可以用于執(zhí)行視頻穩(wěn)定操作。
在添加元數(shù)據(jù)曲目時,曲目的 MIME 格式必須以前綴“application/”開頭。除了數(shù)據(jù)不是來源于 MediaCodec 以外,寫入元數(shù)據(jù)的操作與寫入視頻/音頻數(shù)據(jù)相同。相反,應(yīng)用將包含相關(guān)時間戳的 ByteBuffer 傳遞給 [writeSampleData()](https://developer.android.com/reference/android/media/MediaMuxer#writeSampleData(int,%20java.nio.ByteBuffer,%20android.media.MediaCodec.BufferInfo)) 函數(shù)。時間戳必須和視頻及音頻曲目處于相同的時基。
生成的 MP4 文件使用 ISOBMFF 的 12.3.3.2 部分定義的 TextMetaDataSampleEntry,指示元數(shù)據(jù)的 MIME 格式。在使用 [MediaExtractor](https://developer.android.com/reference/android/media/MediaExtractor) 提取包含元數(shù)據(jù)曲目的文件時,元數(shù)據(jù)的 MIME 格式將提取到 [MediaFormat](https://developer.android.com/reference/android/media/MediaFormat) 中。
音頻播放控制
Android 8.0 允許您查詢和請求設(shè)備產(chǎn)生聲音的方式。對音頻播放的以下控制將讓您的服務(wù)更輕松地僅在有利的設(shè)備條件下產(chǎn)生聲音。
Google 智能助理的新音頻使用類型
[AudioAttributes](https://developer.android.com/reference/android/media/AudioAttributes) 類包含一種新的聲音類型,即 [USAGE_ASSISTANT](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_ASSISTANT),對應(yīng)于 Google 智能助理在設(shè)備上的回答。
設(shè)備音頻播放的變更
如果您希望自己的服務(wù)僅在特定的設(shè)備音頻配置處于活動狀態(tài)時開始產(chǎn)生聲音,您可以使用 [AudioManager](https://developer.android.com/reference/android/media/AudioManager) 類注冊一個 [AudioManager.AudioPlaybackCallback](https://developer.android.com/reference/android/media/AudioManager.AudioPlaybackCallback) 實例,后者的[onPlaybackConfigChanged()](https://developer.android.com/reference/android/media/AudioManager.AudioPlaybackCallback#onPlaybackConfigChanged(java.util.List%3Candroid.media.AudioPlaybackConfiguration%3E)) 函數(shù)可以幫助您確定當(dāng)前活動的音頻屬性集。
顯式請求音頻焦點
您的服務(wù)可以使用 [requestAudioFocus()](https://developer.android.com/reference/android/media/AudioManager#requestAudioFocus(android.media.AudioFocusRequest)) 函數(shù)提交一個更精細的設(shè)備級音頻焦點接收請求。傳入一個 AudioFocusRequest 對象,您可以使用 AudioFocusRequest.Builder 創(chuàng)建這個對象。在這個構(gòu)建類中,您可以指定以下選項:
- 您希望獲得的焦點類型,例如
AUDIOFOCUS_GAIN_TRANSIENT或AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK。 - 當(dāng)另一個音頻服務(wù)獲得設(shè)備焦點時,您的服務(wù)應(yīng)以更安靜的方式繼續(xù),還是完全暫停。
- 您的服務(wù)能否等待獲得焦點,直至設(shè)備就緒。
注:構(gòu)建您的 AudioFocusRequest 實例時,如果您通過調(diào)用 setAcceptsDelayedFocusGain() 指示您的服務(wù)可以等待產(chǎn)生聲音,您也必須調(diào)用 setOnAudioFocusChangeListener(),以便您的服務(wù)了解它何時可以開始產(chǎn)生聲音。
增強的媒體文件訪問功能
存儲訪問框架 (SAF) 允許應(yīng)用顯示自定義 [DocumentsProvider](https://developer.android.com/reference/android/provider/DocumentsProvider),后者可以為其他應(yīng)用提供訪問數(shù)據(jù)源中的文件的權(quán)限。事實上,文檔提供程序甚至可以提供駐留在網(wǎng)絡(luò)存儲區(qū)或使用媒體傳輸協(xié)議 (MTP) 等協(xié)議的文件的訪問權(quán)限。
但是,訪問遠程數(shù)據(jù)源中的大媒體文件面臨一些挑戰(zhàn):
- 媒體播放器需要以尋址方式訪問來自文檔提供程序的文件。當(dāng)大媒體文件駐留在遠程數(shù)據(jù)源上時,文檔提供程序必須事先提取所有數(shù)據(jù),并創(chuàng)建快照文件描述符。媒體播放器無法播放沒有文件描述符的文件,因此在文檔提供程序完成文件下載前,無法開始播放。
- 照片應(yīng)用等媒體集合管理器必須通過作用域文件夾遍歷一系列訪問 URI 才能訪問存儲在外部 SD 卡上的媒體。這種訪問模式會讓媒體上的批量操作(例如移動、復(fù)制和刪除)變得非常緩慢。
- 媒體集合管理器無法根據(jù)文檔的 URI 確定其位置。這就讓這些類型的應(yīng)用難以允許用戶選擇媒體文件的保存位置。
Android 8.0 通過改進存儲訪問框架解決了各個挑戰(zhàn)。
自定義文檔提供程序
從 Android 8.0 開始,存儲訪問框架允許自定義文檔提供程序為駐留在遠程數(shù)據(jù)源中的文件創(chuàng)建可尋址的文件描述符。SAF 可打開文件,獲取原生可尋址的文件描述符。然后 SAF 向文檔提供程序提交離散字節(jié)請求。此功能使文檔提供程序可以返回媒體播放器應(yīng)用請求的準確字節(jié)范圍,而不必事先緩存整個文件。
要使用此功能,您需要調(diào)用新的 [StorageManager.openProxyFileDescriptor()](https://developer.android.com/reference/android/os/storage/StorageManager#openProxyFileDescriptor(int,%20android.os.ProxyFileDescriptorCallback,%20android.os.Handler)) 函數(shù)。[openProxyFileDescriptor()](https://developer.android.com/reference/android/os/storage/StorageManager#openProxyFileDescriptor(int,%20android.os.ProxyFileDescriptorCallback,%20android.os.Handler)) 函數(shù)可接受 [ProxyFileDescriptorCallback](https://developer.android.com/reference/android/os/ProxyFileDescriptorCallback) 對象作為回調(diào)。任何時候,當(dāng)客戶端應(yīng)用對文檔提供程序返回的文件描述符執(zhí)行文件操作時,SAF 都會調(diào)用回調(diào)。
直接文檔訪問
從 Android 8.0 開始,您可以使用 [getDocumentUri()](https://developer.android.com/reference/android/provider/MediaStore#getDocumentUri(android.content.Context,%20android.net.Uri)) 函數(shù)獲得與給定 mediaUri 引用相同文檔的 URI。不過,由于返回的 URI 由 [DocumentsProvider](https://developer.android.com/reference/android/provider/DocumentsProvider) 提供支持,媒體集合管理器可以直接訪問文檔,不用遍歷作用域目錄樹。因此,媒體管理器能夠以明顯加快的速度對文檔執(zhí)行文件操作。
注意:[getDocumentUri()](https://developer.android.com/reference/android/provider/MediaStore#getDocumentUri(android.content.Context,%20android.net.Uri)) 函數(shù)僅可以定位媒體文件;無法授予應(yīng)用訪問這些文件的權(quán)限。要詳細了解如何獲取媒體文件的訪問權(quán)限,請參閱參考文檔。
文檔路徑
在 Android 8.0 中使用存儲訪問框架時,您可以根據(jù)文檔的 ID,使用 findDocumentPath() 函數(shù)(存在于 [DocumentsContract](https://developer.android.com/reference/android/provider/DocumentsContract#findDocumentPath(android.content.ContentResolver,%20android.net.Uri)) 和 [DocumentsProvider](https://developer.android.com/reference/android/provider/DocumentsProvider#findDocumentPath(java.lang.String,%20java.lang.String)) 類中)從文件系統(tǒng)的根目錄中確定路徑。該函數(shù)將在 [DocumentsContract.Path](https://developer.android.com/reference/android/provider/DocumentsContract.Path) 對象中返回此路徑。如果文件系統(tǒng)對相同文檔有多個定義的路徑,該函數(shù)將返回訪問具有給定 ID 的文檔時最常使用的路徑。
此功能在下列情況下特別有用:
- 您的應(yīng)用使用可以顯示特定文檔位置的“另存為”對話框。
- 您的應(yīng)用在搜索結(jié)果視圖中顯示文件夾并且如果用戶選擇某個文件夾,應(yīng)用必須加載此特定文件夾內(nèi)的子文檔。
注:如果您的應(yīng)用僅具有路徑中某些文檔的訪問權(quán)限,那么 findDocumentPath() 的返回值將僅包含您的應(yīng)用可以訪問的文件夾和文檔。
連接
WLAN 感知
Android 8.0 新增了對 WLAN 感知的支持,此技術(shù)基于周邊感知聯(lián)網(wǎng) (NAN) 規(guī)范。在具有相應(yīng) WLAN 感知硬件的設(shè)備上,應(yīng)用和附近設(shè)備可以通過 WLAN 進行搜索和通信,無需依賴互聯(lián)網(wǎng)接入點。我們正在與硬件合作伙伴合作,以盡快將 WLAN 感知技術(shù)應(yīng)用于設(shè)備。要了解有關(guān)如何將 WLAN 感知集成到您的應(yīng)用中的信息,請參閱 WLAN 感知。
藍牙
Android 8.0 通過增加以下功能,增強了平臺對藍牙的支持:
- 支持 AVRCP 1.4 標準,該標準支持音樂庫瀏覽。
- 支持藍牙低功耗 (BLE) 5.0 標準。
- 將 Sony LDAC 編解碼器集成到藍牙堆疊中。
配套設(shè)備配對
在嘗試通過藍牙、BLE 和 WLAN 與配套設(shè)備配對時,Android 8.0 提供的 API 允許您自定義配對請求對話框。如需了解詳細信息,請參閱配套設(shè)備配對。
如需了解有關(guān)在 Android 上使用藍牙的詳細信息,請參閱藍牙指南。有關(guān)對藍牙所作的特定于 Android 8.0 的變更,請參閱 Android 8.0 行為變更頁面的藍牙部分。
共享
智能共享
Android 8.0 了解用戶的個性化分享首選項,在通過哪些應(yīng)用分享各個類型的內(nèi)容方面,也有著更好的把握。例如,如果用戶為一張收據(jù)拍照,Android 8.0 可以建議費用跟蹤應(yīng)用;如果用戶自拍,一款社交媒體應(yīng)用可以更好地處理圖像。Android 8.0 可以根據(jù)用戶的個性化首選項自動學(xué)習(xí)所有這些模式。
智能分享適用于 image 之外的內(nèi)容類型,例如 audio、video、text 和 URL 等。
要啟用智能分享,請將具有最多三個字符串注釋的 [ArrayList](https://developer.android.com/reference/java/util/ArrayList) 添加到分享內(nèi)容的 intent。這些注釋應(yīng)說明內(nèi)容中的主要部分或主題。下面的代碼示例顯示了如何向 intent 添加注釋:
ArrayList<String> annotations = new ArrayList<>();
annotations.add("topic1");
annotations.add("topic2");
annotations.add("topic3");
intent.putStringArrayListExtra(
Intent.EXTRA_CONTENT_ANNOTATIONS,
annotations
);
如需了解有關(guān)智能分享注釋的詳細信息,請參閱 [EXTRA_CONTENT_ANNOTATIONS](https://developer.android.com/reference/android/content/Intent#EXTRA_CONTENT_ANNOTATIONS)。
智能文本選擇
在兼容設(shè)備上,Android 8.0 讓應(yīng)用可以幫助用戶以更有意義的方式與文本交互。當(dāng)用戶長按某個實體中可識別格式的單詞(例如某個地址或餐館名稱)時,系統(tǒng)會選中整個實體。用戶會看到一個浮動工具欄,該工具欄包含可以處理所選文本實體的應(yīng)用。例如,如果系統(tǒng)識別出某個地址,它可以將用戶導(dǎo)向地圖應(yīng)用。
系統(tǒng)識別的實體包括地址、網(wǎng)址、電話號碼和電子郵件地址。如需了解詳細信息,請參閱 [TextClassifier](https://developer.android.com/reference/android/view/textclassifier/TextClassifier)。
無障礙功能
Android 8.0 支持開發(fā)者使用以下無障礙功能創(chuàng)建自己的無障礙服務(wù)。如需了解有關(guān)如何讓您的應(yīng)用更便于訪問的更多信息,請參閱無障礙功能。
無障礙功能按鈕
您的無障礙服務(wù)現(xiàn)在可以請求在系統(tǒng)的導(dǎo)航區(qū)域顯示無障礙功能按鈕,該按鈕讓用戶可從其設(shè)備上的任意位置快速激活您的服務(wù)功能。要執(zhí)行此操作,請在某個 [AccessibilityServiceInfo](https://developer.android.com/reference/android/accessibilityservice/AccessibilityServiceInfo) 對象的 android:accessibilityFlags 屬性中添加 [FLAG_REQUEST_ACCESSIBILITY_BUTTON](https://developer.android.com/reference/android/accessibilityservice/AccessibilityServiceInfo#FLAG_REQUEST_ACCESSIBILITY_BUTTON) 標志。稍后,您可以使用 [registerAccessibilityButtonCallback()](https://developer.android.com/reference/android/accessibilityservice/AccessibilityButtonController#registerAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback)) 注冊回調(diào)。
注:此功能僅適用于提供軟件渲染導(dǎo)航區(qū)域的設(shè)備。請始終使用 [isAccessibilityButtonAvailable()](https://developer.android.com/reference/android/accessibilityservice/AccessibilityButtonController#isAccessibilityButtonAvailable()),并通過實現(xiàn) [onAvailabilityChanged()](https://developer.android.com/reference/android/accessibilityservice/AccessibilityButtonController.AccessibilityButtonCallback#onAvailabilityChanged(android.accessibilityservice.AccessibilityButtonController,%20boolean)) 根據(jù)無障礙功能按鈕的可用性來響應(yīng)變更。通過該方式,用戶可以始終訪問您的服務(wù)功能,即使該無障礙功能按鈕不受支持或變得不可用。
獨立的音量調(diào)整
Android 8.0 引入了 [STREAM_ACCESSIBILITY](https://developer.android.com/reference/android/media/AudioManager#STREAM_ACCESSIBILITY) 音量類別,允許您單獨控制無障礙服務(wù)音頻輸出的音量,而不會影響設(shè)備上的其他聲音。
要使用這個新的流類型來控制無障礙服務(wù)音量,請在無障礙服務(wù)中設(shè)置 [FLAG_ENABLE_ACCESSIBILITY_VOLUME](https://developer.android.com/reference/android/accessibilityservice/AccessibilityServiceInfo#FLAG_ENABLE_ACCESSIBILITY_VOLUME) 選項。然后,您可以使用 [adjustStreamVolume()](https://developer.android.com/reference/android/media/AudioManager#adjustStreamVolume(int,%20int,%20int)) 更改設(shè)備的無障礙服務(wù)音頻音量。
指紋手勢
您的無障礙服務(wù)也可以響應(yīng)替代的輸入機制,即沿設(shè)備的指紋傳感器按特定方向滑動(上、下、左和右)。要接收有關(guān)這些交互的回調(diào),請完成以下一系列步驟:
- 聲明
USE_FINGERPRINT權(quán)限和[CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES](https://developer.android.com/reference/android/accessibilityservice/AccessibilityServiceInfo#CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES)功能。 - 在
android:accessibilityFlags屬性中設(shè)置[FLAG_REQUEST_FINGERPRINT_GESTURES](https://developer.android.com/reference/android/accessibilityservice/AccessibilityServiceInfo#FLAG_REQUEST_FINGERPRINT_GESTURES)標志。 - 使用
[registerFingerprintGestureCallback()](https://developer.android.com/reference/android/accessibilityservice/FingerprintGestureController#registerFingerprintGestureCallback(android.accessibilityservice.FingerprintGestureController.FingerprintGestureCallback,%20android.os.Handler))注冊回調(diào)。
請記住,并非所有設(shè)備都包含指紋傳感器。您可以使用 [isHardwareDetected()](https://developer.android.com/reference/android/hardware/fingerprint/FingerprintManager#isHardwareDetected()) 函數(shù)識別設(shè)備是否支持此傳感器。即使對于包含指紋傳感器的設(shè)備,您的服務(wù)也只有在指紋傳感器不用于身份驗證目的時才可使用它。要識別此傳感器何時可用,請調(diào)用 [isGestureDetectionAvailable()](https://developer.android.com/reference/android/accessibilityservice/FingerprintGestureController#isGestureDetectionAvailable()) 函數(shù)并實現(xiàn) [onGestureDetectionAvailabilityChanged()](https://developer.android.com/reference/android/accessibilityservice/FingerprintGestureController.FingerprintGestureCallback#onGestureDetectionAvailabilityChanged(boolean)) 回調(diào)。
字詞級突出顯示
要確定 [TextView](https://developer.android.com/reference/android/widget/TextView) 對象中可見字符的位置,您可以在 [EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY) 中將其作為第一個參數(shù)傳遞到 [refreshWithExtraData()](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#refreshWithExtraData(java.lang.String,%20android.os.Bundle)) 中。隨后會更新您為 [refreshWithExtraData()](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#refreshWithExtraData(java.lang.String,%20android.os.Bundle)) 提供的作為第二個參數(shù)的 [Bundle](https://developer.android.com/reference/android/os/Bundle) 對象,使之包含一個可打包的 [Rect](https://developer.android.com/reference/android/graphics/Rect) 對象數(shù)組。每個 [Rect](https://developer.android.com/reference/android/graphics/Rect) 對象代表某個特定字符的邊界框。
如果您的服務(wù)使用 [TextToSpeech](https://developer.android.com/reference/android/speech/tts/TextToSpeech) 對象朗讀屏幕上出現(xiàn)的內(nèi)容,您可以獲取有關(guān)文本到語音轉(zhuǎn)換引擎何時開始朗讀單個合成字詞時的準確時間信息,前提是文本到語音轉(zhuǎn)換引擎提供此信息。當(dāng)引擎即將開始播放特定范圍文本的音頻時,Text-to-Speech API 會通知您的服務(wù),將使用 [onRangeStart()](https://developer.android.com/reference/android/speech/tts/UtteranceProgressListener#onRangeStart(java.lang.String,%20int,%20int,%20int)) 函數(shù)開始朗讀此范圍的文本。
如果您創(chuàng)建自己的 [TextToSpeechService](https://developer.android.com/reference/android/speech/tts/TextToSpeechService) 實現(xiàn),您可以使用 [rangeStart()](https://developer.android.com/reference/android/speech/tts/SynthesisCallback#rangeStart(int,%20int,%20int)) 函數(shù)支持這一新功能。
標準化單端范圍值
[AccessibilityNodeInfo](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo) 的一些實例使用 [AccessibilityNodeInfo.RangeInfo](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo.RangeInfo) 的某個實例來表明界面元素可接受一定范圍的值。使用 [RangeInfo.obtain()](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo.RangeInfo#obtain(int,%20float,%20float,%20float)) 創(chuàng)建范圍或使用 [getMin()](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo.RangeInfo#getMin()) 和 [getMax()](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo.RangeInfo#getMax()) 檢索此范圍的極值時,請注意,Android 8.0 規(guī)定了標準化單端范圍:
- 對于沒有最小值的范圍,
[Float.NEGATIVE_INFINITY](https://developer.android.com/reference/java/lang/Float#NEGATIVE_INFINITY)表示最小值。 - 對于沒有最大值的范圍,
[Float.POSITIVE_INFINITY](https://developer.android.com/reference/java/lang/Float#POSITIVE_INFINITY)表示最大值。
提示文本
Android 8.0 包含可用于與文本可編輯對象的提示文本進行交互的多個函數(shù):
-
[isShowingHintText()](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#isShowingHintText())和[setShowingHintText()](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#setShowingHintText(boolean))函數(shù)分別顯示和設(shè)置節(jié)點的當(dāng)前文本內(nèi)容是否表示節(jié)點的提示文本。如果節(jié)點不包含可編輯文本,則它不應(yīng)包含提示文本。 - 要訪問提示文本本身,請使用
[getHintText()](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#getHintText())。即使某個對象當(dāng)前未顯示提示文本,系統(tǒng)也能成功調(diào)用[getHintText()](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#getHintText())。
連續(xù)的手勢分派
您的服務(wù)現(xiàn)在可以使用 [GestureDescription.StrokeDescription](https://developer.android.com/reference/android/accessibilityservice/GestureDescription.StrokeDescription) 構(gòu)造函數(shù)中的最后一個參數(shù) willContinue,指定屬于同一設(shè)定手勢的筆劃的順序。
安全性與隱私
權(quán)限
Android 8.0 引入了多個與電話有關(guān)的新權(quán)限:
-
ANSWER_PHONE_CALLS允許您的應(yīng)用通過編程方式接聽呼入電話。要在您的應(yīng)用中處理呼入電話,您可以使用[acceptRingingCall()](https://developer.android.com/reference/android/telecom/TelecomManager#acceptRingingCall())函數(shù)。 -
READ_PHONE_NUMBERS權(quán)限允許您的應(yīng)用讀取設(shè)備中存儲的電話號碼。
這些權(quán)限均被劃分為危險類別,屬于 PHONE 權(quán)限組。
新的帳號訪問和 Discovery API
Android 8.0 對應(yīng)用訪問用戶帳號的方式引入多項改進。對于由身份驗證器管理的帳號,身份驗證器在決定對應(yīng)用隱藏帳號還是顯示帳號時可以使用自己的策略。Android 系統(tǒng)跟蹤可以訪問特定帳號的應(yīng)用。
在以前的 Android 版本中,想要跟蹤用戶帳號列表的應(yīng)用必須獲取有關(guān)所有帳號的更新,包括具有不相關(guān)類型的帳號。Android 8.0 添加了 [addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[])](https://developer.android.com/reference/android/accounts/AccountManager#addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener,%20android.os.Handler,%20boolean,%20java.lang.String[])) 函數(shù),其允許應(yīng)用指定應(yīng)接收帳號變更的帳號類型列表。
API 變更
AccountManager 提供六個新函數(shù)以幫助身份驗證器管理哪些應(yīng)用可以查看某個帳號:
-
[setAccountVisibility(android.accounts.Account, java.lang.String, int)](https://developer.android.com/reference/android/accounts/AccountManager#setAccountVisibility(android.accounts.Account,%20java.lang.String,%20int)):針對特定用戶帳號和軟件包組合設(shè)置可見性級別。 -
[getAccountVisibility(android.accounts.Account, java.lang.String)](https://developer.android.com/reference/android/accounts/AccountManager#getAccountVisibility(android.accounts.Account,%20java.lang.String)):獲取特定用戶帳號和軟件包組合的可見性級別。 -
[getAccountsAndVisibilityForPackage(java.lang.String, java.lang.String)](https://developer.android.com/reference/android/accounts/AccountManager#getAccountsAndVisibilityForPackage(java.lang.String,%20java.lang.String)):允許身份驗證器獲取帳號和給定軟件包的可見性級別。 -
[getPackagesAndVisibilityForAccount(android.accounts.Account)](https://developer.android.com/reference/android/accounts/AccountManager#getPackagesAndVisibilityForAccount(android.accounts.Account)):允許身份驗證器獲取存儲的給定帳號的可見性值。 -
[addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.String, java.lang.Integer>)](https://developer.android.com/reference/android/accounts/AccountManager#addAccountExplicitly(android.accounts.Account,%20java.lang.String,%20android.os.Bundle,%20java.util.Map%3Cjava.lang.String,%20java.lang.Integer%3E)):允許身份驗證器初始化帳號的可見性值。 -
[addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[])](https://developer.android.com/reference/android/accounts/AccountManager#addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener,%20android.os.Handler,%20boolean,%20java.lang.String[])):將[OnAccountsUpdateListener](https://developer.android.com/reference/android/accounts/OnAccountsUpdateListener)偵聽器添加到[AccountManager](https://developer.android.com/reference/android/accounts/AccountManager)對象。無論設(shè)備上的帳號列表何時發(fā)生變化,系統(tǒng)都將調(diào)用此偵聽器。
Android 8.0 引入兩個特殊的軟件包名稱值,以使用 [setAccountVisibility(android.accounts.Account, java.lang.String, int)](https://developer.android.com/reference/android/accounts/AccountManager#setAccountVisibility(android.accounts.Account,%20java.lang.String,%20int)) 函數(shù)指定未設(shè)置的應(yīng)用的可見性級別。[PACKAGE_NAME_KEY_LEGACY_VISIBLE](https://developer.android.com/reference/android/accounts/AccountManager#PACKAGE_NAME_KEY_LEGACY_VISIBLE) 可見性值應(yīng)用于具有 [GET_ACCOUNTS](https://developer.android.com/reference/android/Manifest.permission#GET_ACCOUNTS) 權(quán)限的應(yīng)用,并且其目標 Android 版本低于 Android 8.0,或其簽名與針對任意 Android 版本的身份驗證器匹配。[PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE](https://developer.android.com/reference/android/accounts/AccountManager#PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE) 為之前未設(shè)置的應(yīng)用提供默認的可見性值,對于此類應(yīng)用,[PACKAGE_NAME_KEY_LEGACY_VISIBLE](https://developer.android.com/reference/android/accounts/AccountManager#PACKAGE_NAME_KEY_LEGACY_VISIBLE) 不適用。
如需了解有關(guān)新的帳號訪問和發(fā)現(xiàn) API 的詳細信息,請參閱 [AccountManager](https://developer.android.com/reference/android/accounts/AccountManager) 和 [OnAccountsUpdateListener](https://developer.android.com/reference/android/accounts/OnAccountsUpdateListener) 參考。
Google Safe Browsing API
[WebView](https://developer.android.com/reference/android/webkit/WebView) 類現(xiàn)在添加了一個 Safe Browsing API 來增強網(wǎng)絡(luò)瀏覽的安全性。如需了解詳細信息,請參閱 Google Safe Browsing API。
測試
儀器測試
Android 8.0 為應(yīng)用的儀器測試提供以下幾項額外支持。
針對非默認應(yīng)用進程運行
現(xiàn)在,您可以指定針對您的應(yīng)用的默認進程以外的進程運行特定儀器測試。如果您的應(yīng)用包含多個在不同進程中運行的操作組件,此配置非常有用。
要定義非默認進程儀器測試,請導(dǎo)航至您的清單文件,然后導(dǎo)航至所需的 <instrumentation> 元素。添加 android:targetProcess 屬性,并將它的值設(shè)置為以下值之一:
- 特定進程的名稱。
- 以逗號分隔的進程名稱列表。
- 通配符(
"*"),允許針對任何執(zhí)行android:targetPackage屬性中指定的軟件包中的代碼的已啟動進程運行儀器測試。
在執(zhí)行儀器測試時,您可以通過調(diào)用 [getProcessName()](https://developer.android.com/reference/android/app/Instrumentation#getProcessName()) 檢查正在測試哪個進程。
在測試過程中報告結(jié)果
現(xiàn)在,通過調(diào)用 [addResults()](https://developer.android.com/reference/android/app/Instrumentation#addResults(android.os.Bundle)),您可以在執(zhí)行儀器測試時(而不用等到測試后)報告結(jié)果。
用于測試的模擬 Intent
為了更輕松地為您應(yīng)用的操作組件創(chuàng)建隔離、獨立的界面測試,Android 8.0 引入了 [onStartActivity()](https://developer.android.com/reference/android/app/Instrumentation.ActivityMonitor#onStartActivity(android.content.Intent)) 函數(shù)。要處理您的測試類調(diào)用的特定 intent,您可以在 [Instrumentation.ActivityMonitor](https://developer.android.com/reference/android/app/Instrumentation.ActivityMonitor) 類的自定義子類中替換此函數(shù)。
當(dāng)您的測試類調(diào)用 intent 時,該函數(shù)將返回一個存根 [Instrumentation.ActivityResult](https://developer.android.com/reference/android/app/Instrumentation.ActivityResult) 對象,而不是執(zhí)行 intent 本身。通過在您的測試中使用這種模擬 intent 邏輯,您可以側(cè)重于自己的操作組件如何準備和處理您傳遞到不同操作組件或完全不同的應(yīng)用中的 intent。
運行時和工具
平臺優(yōu)化
Android 8.0 為平臺引入了運行時優(yōu)化和其他優(yōu)化,這些優(yōu)化將帶來多項性能改進。這些優(yōu)化包括并發(fā)壓縮垃圾回收、更有效的內(nèi)存利用和代碼區(qū)域。
它們可以加快啟動時間,并為 OS 和應(yīng)用帶來更好的性能。
更新的 Java 支持
Android 8.0 添加了對更多 OpenJDK Java API 的支持:
- OpenJDK 8 中的
[java.time](https://developer.android.com/reference/java/time/package-summary)。 - OpenJDK 7 中的
[java.nio.file](https://developer.android.com/reference/java/nio/file/package-summary)和[java.lang.invoke](https://developer.android.com/reference/java/lang/invoke/package-summary)。
要詳細了解這些新添加的軟件包中的類和函數(shù),請參閱 API 參考文檔。
如果您想要在 Android Studio 中使用 Java 8 語言功能,您應(yīng)下載最新的預(yù)覽版本。
更新的 ICU4J Android Framework API
Android 8.0 擴展了 ICU4J Android 框架 API—,它是 ICU4J API 的子集—,供應(yīng)用開發(fā)者在 android.icu 軟件包中使用。這些 API 使用設(shè)備上具有的本地化數(shù)據(jù)。因此,您無需在 APK 中編譯 ICU4J 庫,從而減少 APK 占用空間。
表 1. Android 中使用的 ICU、CLDR 和 Unicode 版本。
| Android API 級別 | ICU 版本 | CLDR 版本 | Unicode 版本 |
| Android 7.0(API 級別 24),Android 7.1(API 級別 25) | 56 | 28 | 8.0 |
| Android 8.0 | 58.2 | 30.0.3 | 9.0 |
如需詳細了解針對受支持的 ICU4J API 的更新,請閱讀版本說明。
Android 企業(yè)版
已為運行 Android 8.0 的設(shè)備引入新的企業(yè)功能和 API。重要功能包括如下:
- 完全托管的設(shè)備中的工作資料使企業(yè)可以在管理工作數(shù)據(jù)與個人數(shù)據(jù)的同時,將它們分離開來。
- API 委派允許設(shè)備所有者和個人資料所有者將應(yīng)用管理分配給其他應(yīng)用。
- 配置流程中的用戶體驗改進措施(包含新的自定義選項)縮短了設(shè)置時間。
- 藍牙、WLAN、備份和安全性方面的新增控制選項使企業(yè)可以更精細地管理設(shè)備。網(wǎng)絡(luò)操作組件日志記錄可幫助企業(yè)追查問題。
如需詳細了解上述及其他新增 Android 企業(yè)版 API 和功能,請參閱企業(yè)中的 Android。