Android 8.0 功能和 API

Android 8.0 爲用戶和開發者引入多種新功能。本文重點介紹面向開發者的新功能。

用戶體驗

通知

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

  • 通知渠道:Android 8.0 引入了通知渠道,其允許您爲要顯示的每種通知類型創建用戶可自定義的渠道。用戶界面將通知渠道稱之爲通知類別。要了解如何實現通知渠道的信息,請參閱通知渠道指南。
  • 通知標誌:Android 8.0 引入了對在應用啓動器圖標上顯示通知標誌的支持。通知標誌可反映某個應用是否存在與其關聯、並且用戶尚未予以清除也未對其採取行動的通知。通知標誌也稱爲通知點。要了解如何調整通知標誌,請參閱通知標誌指南。
  • 休眠:用戶可以將通知置於休眠狀態,以便稍後重新顯示它。重新顯示時通知的重要程度與首次顯示時相同。應用可以移除或更新已休眠的通知,但更新休眠的通知並不會使其重新顯示。
  • 通知超時:現在,使用 setTimeoutAfter() 創建通知時您可以設置超時。您可以使用此函數指定一個持續時間,超過該持續時間後,通知應取消。如果需要,您可以在指定的超時持續時間之前取消通知。
  • 通知設置:當您使用Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCESIntent 從通知創建指向應用通知設置的鏈接時,您可以調用 setSettingsText() 來設置要顯示的文本。此係統可以提供以下 Extra 數據和 Intent,用於過濾應用必須向用戶顯示的設置:EXTRA_CHANNEL_ID、NOTIFICATION_TAG 和 NOTIFICATION_ID。
  • 通知清除:系統現在可區分通知是由用戶清除,還是由應用移除。要查看清除通知的方式,您應實現 NotificationListenerService 類的新 onNotificationRemoved() 函數。
  • 背景顏色:您現在可以設置和啓用通知的背景顏色。只能在用戶必須一眼就能看到的持續任務的通知中使用此功能。例如,您可以爲與駕車路線或正在進行的通話有關的通知設置背景顏色。您還可以使用 Notification.Builder.setColor() 設置所需的背景顏色。這樣做將允許您使用 Notification.Builder.setColorized() 啓用通知的背景顏色設置。
  • 消息樣式:現在,使用 MessagingStyle 類的通知可在其摺疊形式中顯示更多內容。對於與消息有關的通知,您應使用 MessagingStyle 類。您還可以使用新的 addHistoricMessage() 函數,通過向與消息相關的通知添加歷史消息爲會話提供上下文。

用戶可以長按應用啓動器圖標以查看 Android 8.0 中的通知

自動填充框架

帳號創建、登錄和信用卡交易需要時間並且容易出錯。在使用要求執行此類重複性任務的應用時,用戶很容易遭受挫折。

Android 8.0 通過引入自動填充框架,簡化了登錄和信用卡表單之類表單的填寫工作。在用戶選擇接受自動填充之後,新老應用都可使用自動填充框架。

您可以採取某些措施,優化您的應用使用此框架的方式。如需瞭解詳細信息,請參閱自動填充框架概覽。

畫中畫模式

Android 8.0 允許以畫中畫 (PIP) 模式啓動操作組件。PIP 是一種特殊的多窗口模式,最常用於視頻播放。目前,PIP 模式可用於 Android TV,而 Android 8.0 則讓該功能可進一步用於其他 Android 設備。

當某個 Activity 處於 PIP 模式時,它會處於暫停狀態,但仍應繼續顯示內容。因此,您應確保您的應用在 onPause() 處理程序中進行處理時不會暫停播放。相反,您應在 onStop() 中暫停播放視頻,並在 onStart() 中繼續播放。如需瞭解詳細信息,請參閱多窗口生命週期。

要指定您的 Activity 可以使用 PIP 模式,請在清單中將 android:supportsPictureInPicture 設置爲 true。(從 Android 8.0 開始,如果您打算在 Android TV 或其他 Android 設備上支持 PIP 模式,則無需將 android:resizeableActivity 設置爲 true;只有在您的 Activity 支持其他多窗口模式時,才需要設置 android:resizeableActivity。)

API 變更

Android 8.0 引入一種新的對象 PictureInPictureParams,您可以將該對象傳遞給 PIP 函數來指定某個 Activity 在其處於 PIP 模式時的行爲。此對象還指定了各種屬性,例如操作組件的首選縱橫比。

現在,在添加畫中畫中介紹的現有 PIP 函數可用於所有 Android 設備,而不僅限於 Android TV。此外,Android 8.0 還提供以下函數來支持 PIP 模式:

  • Activity.enterPictureInPictureMode(PictureInPictureParams args):將操作組件置於畫中畫模式。操作組件的縱橫比和其他配置設置均由 args 指定。如果 args 中的任何字段爲空,系統將使用您上次調用 Activity.setPictureInPictureParams() 時所設置的值。
    指定的操作組件被置於屏幕的一角,屏幕剩餘部分則被屏幕顯示的上一個操作組件填滿。進入 PIP 模式的 Activity 將進入暫停狀態,但仍保持已啓動狀態。如果用戶點按此 PIP 操作組件,系統將顯示一個菜單供用戶操作,而在操作組件處於 PIP 狀態期間,不會理會任何觸摸事件。
  • Activity.setPictureInPictureParams():更新操作組件的 PIP 配置設置。如果操作組件目前處於 PIP 模式,則會更新此設置;如果操作組件的縱橫比發生變化,這非常有用。如果操作組件不處於 PIP 模式,則會使用這些配置設置,而不會考慮您調用的 enterPictureInPictureMode() 函數。

可下載字體

Android 8.0 和 Android 支持庫 26 允許您從提供程序應用請求字體,而無需將字體綁定到 APK 中或讓 APK 下載字體。此功能可減小 APK 大小,提高應用安裝成功率,使多個應用可以共享同一種字體。

如需瞭解有關下載字體的詳細信息,請參閱 可下載字體

XML 中的字體

Android 8.0 推出一項新功能,即 XML 中的字體,允許您使用字體作爲資源。這意味着,不再需要以資產的形式捆綁字體。字體在 R 文件中編譯,並且作爲一種資源,可自動用於系統。然後,您可以利用一種新的資源類型 font 來訪問這些字體。

在運行 API 版本 14 及更高版本的設備中,支持庫 26 對此功能提供完全支持。

自動調整 TextView 的大小

Android 8.0 允許您根據 TextView 的大小自動設置文本展開或收縮的大小。這意味着,在不同屏幕上優化文本大小或者優化包含動態內容的文本大小比以往簡單多了。如需瞭解有關如何在 Android 8.0 中自動調整 TextView 的大小的詳細信息,請參閱自動調整 TextView 的大小。

自適應圖標

Android 8.0 引入自適應啓動器圖標。自適應圖標支持視覺效果,可在不同設備型號上顯示爲各種不同的形狀。要了解如何創建自適應圖標,請參閱自適應圖標預覽功能指南。

顏色管理

圖像應用的 Android 開發者現在可以利用支持廣色域彩色顯示的新設備。要顯示廣色域圖像,應用需要在其清單(每個操作組件)中啓用一個標誌,並加載具有嵌入的廣域彩色配置文件(AdobeRGB、Pro Photo RGB、DCI-P3 等)的位圖。

WebView API

Android 8.0 提供多種 API,幫助您管理在應用中顯示網頁內容的 WebView 對象。這些 API 可增強應用的穩定性和安全性,它們包括:

  • Version API
  • Google SafeBrowsing API
  • Termination Handle API
  • Renderer Importance API

固定快捷方式和小部件

Android 8.0 引入了快捷方式和微件的應用內固定功能。在您的應用中,您可以根據用戶權限爲支持的啓動器創建固定的快捷方式和小部件。

如需瞭解詳細信息,請參閱固定快捷方式和微件預覽功能指南。

最大屏幕縱橫比

以 Android 7.1(API 級別 25)或更低版本爲目標平臺的應用默認的最大屏幕縱橫比爲 1.86。針對 Android 8.0 或更高版本的應用沒有默認的最大縱橫比。如果您的應用需要設置最大縱橫比,請使用定義您的操作組件的清單文件中的 maxAspectRatio 屬性。

多顯示器支持

從 Android 8.0 開始,此平臺爲多顯示器提供增強的支持。如果 Activity 支持多窗口模式,並且在具有多顯示器的設備上運行,則用戶可以將 Activity 從一個顯示器移動到另一個顯示器。當應用啓動 Activity 時,此應用可指定 Activity 應在哪個顯示器上運行。

注:如果 Activity 支持多窗口模式,則 Android 8.0
將爲該 Activity 自動啓用多顯示器支持。您應測試您的應用,
確保它在多顯示器環境下可正常運行。

每次只有一個 Activity 可以處於繼續狀態,即使此應用具有多個顯示器。具有焦點的 Activity 將處於繼續狀態,所有其他可見的 Activity 均暫停,但不會停止。如需瞭解有關當多個 Activity 可見時活動生命週期的詳細信息,請參閱多窗口生命週期。

當用戶將 Activity 從一個顯示器移動到另一個顯示器時,系統將調整 Activity 大小,並根據需要發起運行時變更。您的 Activity 可以自行處理配置變更,或允許系統銷燬包含該 Activity 的進程,並以新的尺寸重新創建它。如需瞭解詳細信息,請參閱處理配置變更。

ActivityOptions 提供兩個新函數以支持多個顯示器:

  • setLaunchDisplayId() 指定 Activity 在啓動後應顯示在哪個顯示器上。
  • getLaunchDisplayId() 返回操作組件的當前啓動顯示器。

對 adb shell 進行了擴展,以支持多個顯示器。shell start 命令現在可用於啓動操作組件,並指定操作組件的目標顯示器:

adb shell start <activity_name> --display <display_id>

統一的佈局外邊距和內邊距

Android 8.0 讓您可以更輕鬆地指定 View 元素的對邊使用相同外邊距和內邊距的情形。具體來說,您現在可以在佈局 XML 文件中使用以下屬性:

  • layout_marginVertical,同時定義 layout_marginTop 和 layout_marginBottom。
  • layout_marginHorizontal,同時定義 layout_marginLeft 和 layout_marginRight。
  • paddingVertical,同時定義 paddingTop 和 paddingBottom。
  • paddingHorizontal,同時定義 paddingLeft 和 paddingRight。
注:如果您自定義應用邏輯以支持不同語言和文化(包括文本方向),
請記住,這些屬性不會影響 layout_marginStart、layout_marginEnd、paddingStart 或 paddingEnd
的值。您可以自行設置這些值和新的垂直與水平佈局屬性
來創建取決於文本方向的佈局行爲。

指針捕獲

某些應用(例如遊戲、遠程桌面和虛擬化客戶端)將大大受益於鼠標指針控制。指針捕獲是 Android 8.0 中的一項新功能,可以通過將所有鼠標事件傳遞到您的應用中焦點視圖的方式提供此類控制。

從 Android 8.0 開始,您的應用中的 View 可以請求指針捕獲並定義一個偵聽器來處理捕獲的指針事件。鼠標指針在此模式下將隱藏。如果不再需要鼠標信息,該視圖可以釋放指針捕獲。系統也可以在視圖丟失焦點時(例如,當用戶打開另一個應用時)釋放指針捕獲。

應用類別

在適當的情況下,Android 8.0 允許每個應用聲明其所屬的類別。這些類別用於將應用呈現給用戶的用途或功能類似的應用歸類在一起,例如按流量消耗、電池消耗和存儲消耗將應用歸類。您可以在

Android TV 啓動器

Android 8.0 添加了一種以內容爲中心的全新 Android TV 主屏幕體驗,支持 Android TV 模擬器和 Nexus Player Android 8.0 設備映像。新的主屏幕在對應於頻道的行中組織視頻內容,這些頻道在系統上通過應用填充各個節目。應用可以發佈多個頻道,用戶可以配置他們希望在主屏幕上看到哪些頻道。Android TV 也包含一個 Watch Next 行,此行根據用戶的觀看習慣從應用填充節目。應用也可以提供視頻預覽,這些預覽會在用戶聚焦到節目時自動播放。用於填充頻道和節目的 API 屬於 TvProvider API,這些 API 以 Android 支持庫模塊的形式隨 Android 8.0 分發。

AnimatorSet

從 Android 8.0 開始,AnimatorSet API 現在支持尋道和倒播功能。尋道功能允許您將動畫的位置設置爲指定的時間點處。如果您的應用包含可撤消的操作的動畫,倒播功能會很有用。現在,您不必定義兩組獨立的動畫,而只需反向播放同一組動畫。

輸入和導航

鍵盤導航鍵區

如果您的應用中,某個操作組件使用一種複雜的視圖層次結構(如圖 2 所示),可考慮將多組界面元素組成一個鍵區,簡化鍵盤導航這些元素的操作。用戶可以在 Chromebook 設備上按 Meta+Tab 或 Search+Tab,在不同鍵區之間導航。鍵區的一些範例包括:側面板、導航欄、主內容區域和可能包含多個子元素的元素。

以一個包含五個導航鍵區的操作組件爲例,用戶可以使用鍵盤導航鍵區快捷鍵進行導航。鍵區按以下佈局顯示:頂部面板、左側面板、主內容區域、底部面板和浮動操作按鈕。

要將一個 View 或 ViewGroup 元素設置爲一個鍵區,請在元素的佈局 XML 文件中將 android:keyboardNavigationCluster 屬性設置爲 true,或者將 true 傳遞至應用界面邏輯中的 setKeyboardNavigationCluster()。

注:鍵區不能嵌套,不過,非嵌套鍵區可以顯示在層次結構的不同層級。
如果您嘗試嵌套鍵區,框架僅會將最頂層的 ViewGroup 元素視爲鍵區。

在具有觸摸屏的設備中,您可以將某個鍵區指定的 ViewGroup 對象的 android:touchscreenBlocksFocus 元素設置爲 true,僅允許從鍵區導航進入和離開此鍵區。如果您將此配置應用於某個鍵區,用戶將無法使用 Tab 鍵或箭頭鍵導航進入或離開此鍵區,而是必須按鍵區導航鍵盤組合鍵。

包含 5 個鍵區的操作組件

視圖默認焦點

在 Android 8.0 中,您可以指定在(重新)創建的操作組件繼續運行並且用戶按下鍵盤導航鍵(例如 Tab 鍵)之後應接收焦點的 View。要應用“設爲默認焦點”設置,請在包含界面元素的佈局 XML 文件中將 View 元素的 android:focusedByDefault 屬性設置爲 true,或者將 true 傳遞至應用界面邏輯中的 setFocusedByDefault()。

系統

新的 StrictMode 檢測程序

Android 8.0 添加了三個新的 StrictMode 檢測程序,幫助識別應用可能出現的錯誤:

  • detectUnbufferedIo() 將檢測您的應用何時讀取或寫入未緩衝的數據,這可能極大影響性能。
  • detectContentUriWithoutPermission() 將檢測您的應用在其外部啓動 Activity 時何時意外忘記向其他應用授予權限。
  • detectUntaggedSockets() 將檢測您的應用何時使用網絡流量,而不使用 setThreadStatsTag(int) 將流量標記用於調試目的。

緩存數據

Android 8.0 優化了緩存數據的導航和行爲。現在,每個應用均獲得一定的磁盤空間配額,用於存儲 getCacheQuotaBytes(UUID) 返回的緩存數據。

當系統需要釋放磁盤空間時,將開始從超過配額最多的應用中刪除緩存文件。因此,如果將您的緩存數據量始終保持低於配額的水平,則在必須清除系統中的某些文件時,您的緩存文件將能堅持到最後。系統在決定刪除您的應用中的哪些緩存文件時,將首先考慮刪除最舊的文件(由修改時間確定)。

您還可以針對每個目錄啓用兩種新行爲,以控制系統如何釋放緩存數據:

  • StorageManager.setCacheBehaviorAtomic() 可用於指示某個目錄及其所有內容應作爲一個不可分割的整體進行刪除。
  • setCacheBehaviorTombstone(File, boolean) 可用於指示不應刪除某個目錄內的文件,而應將它們截斷到 0 字節長度,使空文件保持完好。

最後,在需要爲大文件分配磁盤空間時,可考慮使用新的 allocateBytes(FileDescriptor, long) API,它將自動清除屬於其他應用的緩存文件(根據需要),以滿足您的請求。在確定設備是否有足夠的磁盤空間保存您的新數據時,請調用 getAllocatableBytes(UUID) 而不要使用 getUsableSpace(),因爲前者會考慮系統要爲您清除的任何緩存數據。

內容提供程序分頁

我們已更新內容提供程序以支持加載大型數據集,每次加載一頁。例如,一個具有大量圖像的照片應用可查詢要在頁面中顯示的數據的子集。內容提供程序返回的每個結果頁面由一個 Cursor 對象表示。客戶端和提供程序必須實現分頁才能利用此功能。

內容刷新請求

現在,ContentProvider 和 ContentResolver 類均包含 refresh() 函數,這樣,客戶端可以更輕鬆地知道所請求的信息是否爲最新信息。

您可以擴展 ContentProvider 以添加自定義的內容刷新邏輯。請務必重寫 refresh() 函數,以返回 true,告知提供程序的客戶端您已嘗試自行刷新數據。

您的客戶端應用可通過調用另一個函數(又稱 refresh()),顯式請求已刷新的內容。在調用此函數時,傳入待刷新數據的 URI。

注:由於您可能通過網絡不斷請求數據,
您應僅在有明顯跡象表明內容確已過時時才從客戶端調用 refresh()。
執行此類內容刷新最常見的原因是響應滑動刷新手勢,
該手勢顯式請求當前界面顯示最新內容。

JobScheduler 改進

Android 8.0 引入了對 JobScheduler 的多項改進。由於您通常可以使用計劃作業替代現在受限的後臺服務或隱式廣播接收器,這些改進可以讓您的應用更輕鬆地符合新的後臺執行限制。

JobScheduler 的更新包括:

  • 您現在可以將工作隊列與計劃作業關聯。要將一個工作項添加到作業的隊列中,請調用 JobScheduler.enqueue()。當作業運行時,它可以將待定工作從隊列中剝離並進行處理。這種功能可以處理之前需要啓動後臺服務(尤其是實現 IntentService 的服務)的許多用例。
  • 您現在可以通過調用 JobInfo.Builder.setClipData() 的方式將 ClipData 與作業關聯。利用此選項,您可以將 URI 權限授予與作業關聯,類似於這些權限傳遞到 Context.startService() 的方式。您也可以將 URI 權限授予用於工作隊列上的 intent。
  • 計劃作業現在支持多個新的約束條件:JobInfo.isRequireStorageNotLow()
    如果設備的可用存儲空間非常低,作業將不會運行。
    JobInfo.isRequireBatteryNotLow()
    如果電池電量等於或低於臨界閾值,作業將不會運行;臨界閾值是指設備顯示 Low battery warning 系統對話框的電量。
    NETWORK_TYPE_METERED
    作業需要一個按流量計費的網絡連接,比如大多數移動數據網絡數據套餐。

自定義數據存儲

Android 8.0 允許您爲首選項提供自定義數據存儲,如果您的應用將首選項存儲在雲或本地數據庫中,或者如果首選項特定於某個設備,此功能會非常有用。如需瞭解有關實現數據存儲的詳細信息,請參閱自定義數據存儲。

findViewById() 簽名變更

現在,findViewById() 函數的全部實例均返回

  • 例如,如果 someMethod(View) 和 someMethod(TextView) 均接受調用 findViewById() 的結果,這可能導致現有代碼的返回類型不確定。
  • 在使用 Java 8 源語言時,這需要在返回類型不受限制時(例如,assertNotNull(findViewById(...)).someViewMethod()))顯式轉換爲 View。
  • 重寫非最終的 findViewById() 函數(例如,Activity.findViewById())將需要更新其返回類型。

媒體增強功能

VolumeShaper

有一個新的 VolumeShaper 類。您可以用它來執行簡短的自動音量轉換,例如淡入、淡出和交叉淡入淡出。

音頻焦點增強功能

音頻應用通過請求和捨棄音頻焦點的方式在設備上共享音頻輸出。應用通過啓動或停止播放或者閃避音量的方式處理處於聚焦狀態的變更。有一個新的 AudioFocusRequest 類。對於此類,應用在處理音頻焦點變化時會使用新功能:自動閃避和延遲聚焦。

媒體指標

新的 getMetrics() 函數將返回一個包含配置和性能信息的 PersistableBundle 對象,用一個包含屬性和值的地圖表示。爲以下媒體類定義 getMetrics() 函數:

  • MediaPlayer.getMetrics()
  • MediaRecorder.getMetrics()
  • MediaCodec.getMetrics()
  • MediaExtractor.getMetrics()

爲每個實例單獨收集指標,並持續到實例的生命週期結束爲止。如果沒有可用的指標,則此函數將返回 null。返回的實際指標取決於類。

MediaPlayer

Android 8.0 爲 MediaPlayer 類添加了多種新函數。這些函數可以從多個方面增強您的應用處理媒體播放的能力:

  • 在搜索幀時進行精細控制。
  • 播放受數字版權管理保護的材料的功能。

MediaPlayer 現在支持採樣級加密。

音頻錄製器

  • 音頻錄製器現在支持對流式傳輸有用的 MPEG2_TS 格式:mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS);
  • MediaMuxer 現在可以處理任意數量的音頻和視頻流,而不再僅限於一個音頻曲目和/或一個視頻曲目。使用 addTrack() 可混錄所需的任意數量的曲目。
  • MediaMuxer 還可以添加一個或多個包含用戶定義的每幀信息的元數據曲目。元數據的格式由您的應用定義。僅對 MP4 容器支持元數據曲目。

元數據可以用於離線處理。例如,傳感器的陀螺儀信號可以用於執行視頻穩定操作。

在添加元數據曲目時,曲目的 MIME 格式必須以前綴“application/”開頭。除了數據不是來源於 MediaCodec 以外,寫入元數據的操作與寫入視頻/音頻數據相同。相反,應用將包含相關時間戳的 ByteBuffer 傳遞給 writeSampleData() 函數。時間戳必須和視頻及音頻曲目處於相同的時基。

生成的 MP4 文件使用 ISOBMFF 的 12.3.3.2 部分定義的 TextMetaDataSampleEntry,指示元數據的 MIME 格式。在使用 MediaExtractor 提取包含元數據曲目的文件時,元數據的 MIME 格式將提取到 MediaFormat 中。

音頻播放控制

Android 8.0 允許您查詢和請求設備產生聲音的方式。對音頻播放的以下控制將讓您的服務更輕鬆地僅在有利的設備條件下產生聲音。

Google 智能助理的新音頻使用類型

AudioAttributes 類包含一種新的聲音類型,即 USAGE_ASSISTANT,對應於 Google 智能助理在設備上的回答。

設備音頻播放的變更

如果您希望自己的服務僅在特定的設備音頻配置處於活動狀態時開始產生聲音,您可以使用 AudioManager 類註冊一個 AudioManager.AudioPlaybackCallback 實例,後者的onPlaybackConfigChanged() 函數可以幫助您確定當前活動的音頻屬性集。

顯式請求音頻焦點

您的服務可以使用 requestAudioFocus() 函數提交一個更精細的設備級音頻焦點接收請求。傳入一個 AudioFocusRequest 對象,您可以使用 AudioFocusRequest.Builder 創建這個對象。在這個構建類中,您可以指定以下選項:

  • 您希望獲得的焦點類型,例如 AUDIOFOCUS_GAIN_TRANSIENT 或 AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK。
  • 當另一個音頻服務獲得設備焦點時,您的服務應以更安靜的方式繼續,還是完全暫停。
  • 您的服務能否等待獲得焦點,直至設備就緒。

注:構建您的 AudioFocusRequest 實例時,如果您通過調用 setAcceptsDelayedFocusGain() 指示您的服務可以等待產生聲音,您也必須調用 setOnAudioFocusChangeListener(),以便您的服務瞭解它何時可以開始產生聲音。

增強的媒體文件訪問功能

存儲訪問框架 (SAF) 允許應用顯示自定義 DocumentsProvider,後者可以爲其他應用提供訪問數據源中的文件的權限。事實上,文檔提供程序甚至可以提供駐留在網絡存儲區或使用媒體傳輸協議 (MTP) 等協議的文件的訪問權限。

但是,訪問遠程數據源中的大媒體文件面臨一些挑戰:

  • 媒體播放器需要以尋址方式訪問來自文檔提供程序的文件。當大媒體文件駐留在遠程數據源上時,文檔提供程序必須事先提取所有數據,並創建快照文件描述符。媒體播放器無法播放沒有文件描述符的文件,因此在文檔提供程序完成文件下載前,無法開始播放。
  • 照片應用等媒體集合管理器必須通過作用域文件夾遍歷一系列訪問 URI 才能訪問存儲在外部 SD 卡上的媒體。這種訪問模式會讓媒體上的批量操作(例如移動、複製和刪除)變得非常緩慢。
  • 媒體集合管理器無法根據文檔的 URI 確定其位置。這就讓這些類型的應用難以允許用戶選擇媒體文件的保存位置。

Android 8.0 通過改進存儲訪問框架解決了各個挑戰。

自定義文檔提供程序

從 Android 8.0 開始,存儲訪問框架允許自定義文檔提供程序爲駐留在遠程數據源中的文件創建可尋址的文件描述符。SAF 可打開文件,獲取原生可尋址的文件描述符。然後 SAF 向文檔提供程序提交離散字節請求。此功能使文檔提供程序可以返回媒體播放器應用請求的準確字節範圍,而不必事先緩存整個文件。

要使用此功能,您需要調用新的 StorageManager.openProxyFileDescriptor() 函數。openProxyFileDescriptor() 函數可接受 ProxyFileDescriptorCallback 對象作爲回調。任何時候,當客戶端應用對文檔提供程序返回的文件描述符執行文件操作時,SAF 都會調用回調。

直接文檔訪問

從 Android 8.0 開始,您可以使用 getDocumentUri() 函數獲得與給定 mediaUri 引用相同文檔的 URI。不過,由於返回的 URI 由 DocumentsProvider 提供支持,媒體集合管理器可以直接訪問文檔,不用遍歷作用域目錄樹。因此,媒體管理器能夠以明顯加快的速度對文檔執行文件操作。

注意:getDocumentUri() 函數僅可以定位媒體文件;無法授予應用訪問這些文件的權限。要詳細瞭解如何獲取媒體文件的訪問權限,請參閱參考文檔。

文檔路徑

在 Android 8.0 中使用存儲訪問框架時,您可以根據文檔的 ID,使用 findDocumentPath() 函數(存在於 DocumentsContract 和 DocumentsProvider 類中)從文件系統的根目錄中確定路徑。該函數將在 DocumentsContract.Path 對象中返回此路徑。如果文件系統對相同文檔有多個定義的路徑,該函數將返回訪問具有給定 ID 的文檔時最常使用的路徑。

此功能在下列情況下特別有用:

  • 您的應用使用可以顯示特定文檔位置的“另存爲”對話框。
  • 您的應用在搜索結果視圖中顯示文件夾並且如果用戶選擇某個文件夾,應用必須加載此特定文件夾內的子文檔。

注:如果您的應用僅具有路徑中某些文檔的訪問權限,那麼 findDocumentPath() 的返回值將僅包含您的應用可以訪問的文件夾和文檔。

連接

WLAN 感知

Android 8.0 新增了對 WLAN 感知的支持,此技術基於周邊感知聯網 (NAN) 規範。在具有相應 WLAN 感知硬件的設備上,應用和附近設備可以通過 WLAN 進行搜索和通信,無需依賴互聯網接入點。我們正在與硬件合作伙伴合作,以儘快將 WLAN 感知技術應用於設備。要了解有關如何將 WLAN 感知集成到您的應用中的信息,請參閱 WLAN 感知。

藍牙

Android 8.0 通過增加以下功能,增強了平臺對藍牙的支持:

  • 支持 AVRCP 1.4 標準,該標準支持音樂庫瀏覽。
  • 支持藍牙低功耗 (BLE) 5.0 標準。
  • 將 Sony LDAC 編解碼器集成到藍牙堆疊中。

配套設備配對

在嘗試通過藍牙、BLE 和 WLAN 與配套設備配對時,Android 8.0 提供的 API 允許您自定義配對請求對話框。如需瞭解詳細信息,請參閱配套設備配對。

如需瞭解有關在 Android 上使用藍牙的詳細信息,請參閱藍牙指南。有關對藍牙所作的特定於 Android 8.0 的變更,請參閱 Android 8.0 行爲變更頁面的藍牙部分。

共享

智能共享

Android 8.0 瞭解用戶的個性化分享首選項,在通過哪些應用分享各個類型的內容方面,也有着更好的把握。例如,如果用戶爲一張收據拍照,Android 8.0 可以建議費用跟蹤應用;如果用戶自拍,一款社交媒體應用可以更好地處理圖像。Android 8.0 可以根據用戶的個性化首選項自動學習所有這些模式。

智能分享適用於 image 之外的內容類型,例如 audio、video、text 和 URL 等。

要啓用智能分享,請將具有最多三個字符串註釋的 ArrayList 添加到分享內容的 intent。這些註釋應說明內容中的主要部分或主題。下面的代碼示例顯示瞭如何向 intent 添加註釋:

ArrayList<String> annotations = new ArrayList<>();

annotations.add("topic1");
annotations.add("topic2");
annotations.add("topic3");

intent.putStringArrayListExtra(
    Intent.EXTRA_CONTENT_ANNOTATIONS,
    annotations
);

智能文本選擇

在兼容設備上,Android 8.0 讓應用可以幫助用戶以更有意義的方式與文本交互。當用戶長按某個實體中可識別格式的單詞(例如某個地址或餐館名稱)時,系統會選中整個實體。用戶會看到一個浮動工具欄,該工具欄包含可以處理所選文本實體的應用。例如,如果系統識別出某個地址,它可以將用戶導向地圖應用。

系統識別的實體包括地址、網址、電話號碼和電子郵件地址。如需瞭解詳細信息,請參閱 TextClassifier。

無障礙功能

ndroid 8.0 支持開發者使用以下無障礙功能創建自己的無障礙服務。如需瞭解有關如何讓您的應用更便於訪問的更多信息,請參閱無障礙功能。

無障礙功能按鈕

您的無障礙服務現在可以請求在系統的導航區域顯示無障礙功能按鈕,該按鈕讓用戶可從其設備上的任意位置快速激活您的服務功能。要執行此操作,請在某個 AccessibilityServiceInfo 對象的 android:accessibilityFlags 屬性中添加 FLAG_REQUEST_ACCESSIBILITY_BUTTON 標誌。稍後,您可以使用 registerAccessibilityButtonCallback() 註冊回調。

注:此功能僅適用於提供軟件渲染導航區域的設備。請始終使用 isAccessibilityButtonAvailable(),並通過實現 onAvailabilityChanged() 根據無障礙功能按鈕的可用性來響應變更。通過該方式,用戶可以始終訪問您的服務功能,即使該無障礙功能按鈕不受支持或變得不可用。

獨立的音量調整

Android 8.0 引入了 STREAM_ACCESSIBILITY 音量類別,允許您單獨控制無障礙服務音頻輸出的音量,而不會影響設備上的其他聲音。

要使用這個新的流類型來控制無障礙服務音量,請在無障礙服務中設置 FLAG_ENABLE_ACCESSIBILITY_VOLUME 選項。然後,您可以使用 adjustStreamVolume() 更改設備的無障礙服務音頻音量。

指紋手勢

您的無障礙服務也可以響應替代的輸入機制,即沿設備的指紋傳感器按特定方向滑動(上、下、左和右)。要接收有關這些交互的回調,請完成以下一系列步驟:

  • 聲明 USE_FINGERPRINT 權限和 CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES 功能。
  • 在 android:accessibilityFlags 屬性中設置 FLAG_REQUEST_FINGERPRINT_GESTURES 標誌。
  • 使用 registerFingerprintGestureCallback() 註冊回調。

請記住,並非所有設備都包含指紋傳感器。您可以使用 isHardwareDetected() 函數識別設備是否支持此傳感器。即使對於包含指紋傳感器的設備,您的服務也只有在指紋傳感器不用於身份驗證目的時纔可使用它。要識別此傳感器何時可用,請調用 isGestureDetectionAvailable() 函數並實現 onGestureDetectionAvailabilityChanged() 回調。

字詞級突出顯示

要確定 TextView 對象中可見字符的位置,您可以在 EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY 中將其作爲第一個參數傳遞到 refreshWithExtraData() 中。隨後會更新您爲 refreshWithExtraData() 提供的作爲第二個參數的 Bundle 對象,使之包含一個可打包的 Rect 對象數組。每個 Rect 對象代表某個特定字符的邊界框。

如果您的服務使用 TextToSpeech 對象朗讀屏幕上出現的內容,您可以獲取有關文本到語音轉換引擎何時開始朗讀單個合成字詞時的準確時間信息,前提是文本到語音轉換引擎提供此信息。當引擎即將開始播放特定範圍文本的音頻時,Text-to-Speech API 會通知您的服務,將使用 onRangeStart() 函數開始朗讀此範圍的文本。

如果您創建自己的 TextToSpeechService 實現,您可以使用 rangeStart() 函數支持這一新功能。

標準化單端範圍值

AccessibilityNodeInfo 的一些實例使用 AccessibilityNodeInfo.RangeInfo 的某個實例來表明界面元素可接受一定範圍的值。使用 RangeInfo.obtain() 創建範圍或使用 getMin() 和 getMax() 檢索此範圍的極值時,請注意,Android 8.0 規定了標準化單端範圍:

  • 對於沒有最小值的範圍,Float.NEGATIVE_INFINITY 表示最小值。
  • 對於沒有最大值的範圍,Float.POSITIVE_INFINITY 表示最大值。

提示文本

Android 8.0 包含可用於與文本可編輯對象的提示文本進行交互的多個函數:

  • isShowingHintText() 和 setShowingHintText() 函數分別顯示和設置節點的當前文本內容是否表示節點的提示文本。如果節點不包含可編輯文本,則它不應包含提示文本。
  • 要訪問提示文本本身,請使用 getHintText()。即使某個對象當前未顯示提示文本,系統也能成功調用 getHintText()。

連續的手勢分派

您的服務現在可以使用 GestureDescription.StrokeDescription 構造函數中的最後一個參數 willContinue,指定屬於同一設定手勢的筆劃的順序。

安全性與隱私

權限

Android 8.0 引入了多個與電話有關的新權限:

  • ANSWER_PHONE_CALLS 允許您的應用通過編程方式接聽呼入電話。要在您的應用中處理呼入電話,您可以使用 acceptRingingCall() 函數。
  • READ_PHONE_NUMBERS 權限允許您的應用讀取設備中存儲的電話號碼。

這些權限均被劃分爲危險類別,屬於 PHONE 權限組。

新的帳號訪問和 Discovery API

Android 8.0 對應用訪問用戶帳號的方式引入多項改進。對於由身份驗證器管理的帳號,身份驗證器在決定對應用隱藏帳號還是顯示帳號時可以使用自己的策略。Android 系統跟蹤可以訪問特定帳號的應用。

在以前的 Android 版本中,想要跟蹤用戶帳號列表的應用必須獲取有關所有帳號的更新,包括具有不相關類型的帳號。Android 8.0 添加了 addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[]) 函數,其允許應用指定應接收帳號變更的帳號類型列表。

API 變更

AccountManager 提供六個新函數以幫助身份驗證器管理哪些應用可以查看某個帳號:

  • setAccountVisibility(android.accounts.Account, java.lang.String, int):針對特定用戶帳號和軟件包組合設置可見性級別。
  • getAccountVisibility(android.accounts.Account, java.lang.String):獲取特定用戶帳號和軟件包組合的可見性級別。
  • getAccountsAndVisibilityForPackage(java.lang.String, java.lang.String):允許身份驗證器獲取帳號和給定軟件包的可見性級別。
  • getPackagesAndVisibilityForAccount(android.accounts.Account):允許身份驗證器獲取存儲的給定帳號的可見性值。
  • addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.String, java.lang.Integer>):允許身份驗證器初始化帳號的可見性值。
  • addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[]):將 OnAccountsUpdateListener 偵聽器添加到 AccountManager 對象。無論設備上的帳號列表何時發生變化,系統都將調用此偵聽器。

Android 8.0 引入兩個特殊的軟件包名稱值,以使用 setAccountVisibility(android.accounts.Account, java.lang.String, int) 函數指定未設置的應用的可見性級別。PACKAGE_NAME_KEY_LEGACY_VISIBLE 可見性值應用於具有 GET_ACCOUNTS 權限的應用,並且其目標 Android 版本低於 Android 8.0,或其簽名與針對任意 Android 版本的身份驗證器匹配。PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE 爲之前未設置的應用提供默認的可見性值,對於此類應用,PACKAGE_NAME_KEY_LEGACY_VISIBLE 不適用。

Google Safe Browsing API

WebView 類現在添加了一個 Safe Browsing API 來增強網絡瀏覽的安全性。如需瞭解詳細信息,請參閱 Google Safe Browsing API

測試

儀器測試

Android 8.0 爲應用的儀器測試提供以下幾項額外支持。

針對非默認應用進程運行

現在,您可以指定針對您的應用的默認進程以外的進程運行特定儀器測試。如果您的應用包含多個在不同進程中運行的操作組件,此配置非常有用。

要定義非默認進程儀器測試,請導航至您的清單文件,然後導航至所需的

  • 特定進程的名稱。
  • 以逗號分隔的進程名稱列表。
  • 通配符("*"),允許針對任何執行 android:targetPackage 屬性中指定的軟件包中的代碼的已啓動進程運行儀器測試。

在執行儀器測試時,您可以通過調用 getProcessName() 檢查正在測試哪個進程。

在測試過程中報告結果

現在,通過調用 addResults(),您可以在執行儀器測試時(而不用等到測試後)報告結果。

用於測試的模擬 Intent

爲了更輕鬆地爲您應用的操作組件創建隔離、獨立的界面測試,Android 8.0 引入了 onStartActivity() 函數。要處理您的測試類調用的特定 intent,您可以在 Instrumentation.ActivityMonitor 類的自定義子類中替換此函數。

當您的測試類調用 intent 時,該函數將返回一個存根 Instrumentation.ActivityResult 對象,而不是執行 intent 本身。通過在您的測試中使用這種模擬 intent 邏輯,您可以側重於自己的操作組件如何準備和處理您傳遞到不同操作組件或完全不同的應用中的 intent。

行時和工具

平臺優化

Android 8.0 爲平臺引入了運行時優化和其他優化,這些優化將帶來多項性能改進。這些優化包括併發壓縮垃圾回收、更有效的內存利用和代碼區域。

它們可以加快啓動時間,併爲 OS 和應用帶來更好的性能。

更新的 Java 支持

Android 8.0 添加了對更多 OpenJDK Java API 的支持:

  • OpenJDK 8 中的 java.time。
  • OpenJDK 7 中的 java.nio.file 和 java.lang.invoke。
    要詳細瞭解這些新添加的軟件包中的類和函數,請參閱 API 參考文檔。

如果您想要在 Android Studio 中使用 Java 8 語言功能,您應下載最新的預覽版本

更新的 ICU4J Android Framework API

Android 8.0 擴展了 ICU4J Android 框架 API—,它是 ICU4J API 的子集—,供應用開發者在 android.icu 軟件包中使用。這些 API 使用設備上具有的本地化數據。因此,您無需在 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
Android 8.0 58.2 30.0.3 9.0

Android 企業版

已爲運行 Android 8.0 的設備引入新的企業功能和 API。重要功能包括如下:

  • 完全託管的設備中的工作資料使企業可以在管理工作數據與個人數據的同時,將它們分離開來。
  • API 委派允許設備所有者和個人資料所有者將應用管理分配給其他應用。
  • 配置流程中的用戶體驗改進措施(包含新的自定義選項)縮短了設置時間。
  • 藍牙、WLAN、備份和安全性方面的新增控制選項使企業可以更精細地管理設備。網絡操作組件日誌記錄可幫助企業追查問題。
    如需詳細瞭解上述及其他新增 Android 企業版 API 和功能,請參閱企業中的 Android

google官網原文鏈接

如果你想第一時間看我的後期文章,掃碼關注公衆號,長期推送Android開發文章、最新動態、開源項目,讓你各種漲姿勢。

      Android開發666 - 安卓開發技術分享
             掃描二維碼加關注

Android開發666

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章