Android 4.4 API

API 級別:19

Android 4.4 (KITKAT) 是 Android 平台的新版本,可為使用者和應用程式開發人員提供新功能。本文件將介紹最值得注意的新 API。

應用程式開發人員應盡快從 SDK Manager 下載 Android 4.4 系統映像檔和 SDK 平台。如果您沒有搭載 Android 4.4 的裝置,無法用來測試應用程式,請使用 Android 4.4 系統映像檔,在 Android 模擬器上測試應用程式。接著,針對 Android 4.4 平台建構應用程式,即可開始使用最新的 API。

更新目標 API 級別

如要針對搭載 Android 4.4 的裝置,進一步最佳化應用程式,您應將 targetSdkVersion 設為 "19",並在 Android 4.4 系統映像檔上安裝,然後測試,再發布含有此變更的更新。

您可以在 Android 4.4 中使用 API,同時支援舊版,方法是在程式碼中加入條件,在執行 minSdkVersion 不支援的 API 前,先檢查系統 API 級別。如要進一步瞭解如何維持向下相容性,請參閱「支援不同平台版本」。

如要進一步瞭解 API 級別的運作方式,請參閱「什麼是 API 級別?」。

重要行為變更

如果您先前曾發布 Android 應用程式,請注意,您的應用程式可能會受到 Android 4.4 的異動影響。

如果應用程式讀取外部儲存空間的資料,則

除非應用程式具有 READ_EXTERNAL_STORAGE 權限,否則在 Android 4.4 上執行時,應用程式無法讀取外部儲存空間中的共用檔案。也就是說,如果沒有權限,就無法再存取 getExternalStoragePublicDirectory() 傳回的目錄中的檔案。不過,如果您只需要存取 getExternalFilesDir() 提供的應用程式專屬目錄,就不需要 READ_EXTERNAL_STORAGE 權限。

如果您的應用程式使用 WebView...

在 Android 4.4 上執行時,應用程式的行為可能會有所不同,尤其是在您將應用程式的 targetSdkVersion 更新為「19」以上時。

WebView 類別和相關 API 的基礎程式碼已升級,以便根據 Chromium 原始碼的最新快照。這項更新可改善多項效能,支援新的 HTML5 功能,並支援對 WebView 內容進行遠端偵錯。這項升級的範圍表示,如果您的應用程式使用 WebView,在某些情況下,其行為可能會受到影響。雖然已記錄已知的行為變更,且只有在您將應用程式的 targetSdkVersion 更新至「19」以上版本時,才會對應用程式造成影響 (新的 WebView 會以「奇異模式」運作,在指定 API 級別 18 以下的應用程式中提供某些舊版功能),但您的應用程式可能會依賴舊版 WebView 的不明行為。

因此,如果您現有的應用程式使用 WebView,請務必盡快在 Android 4.4 上進行測試,並參閱「在 Android 4.4 中遷移至 WebView」,瞭解將 targetSdkVersion 更新至「19」以上版本時,應用程式可能會受到哪些影響。

如果應用程式使用 AlarmManager...

如果將應用程式的 targetSdkVersion 設為「19」以上,則使用 set()setRepeating() 建立的鬧鐘就會不精確。

為提高電力效率,Android 會將所有應用程式在相近時間設定的鬧鐘合併處理,讓系統只喚醒裝置一次,而非多次喚醒來處理每個鬧鐘。

如果鬧鐘未與確切的時鐘時間相關聯,但仍需要在特定時間範圍內 (例如下午 2 點至 4 點) 喚醒鬧鐘,您可以使用新的 setWindow() 方法,該方法會接受鬧鐘的「最早」時間,以及最早時間後的「時間窗口」,系統應在該時間窗口內喚醒鬧鐘。

如果鬧鐘必須固定在特定時刻響鈴 (例如日曆活動提醒),您可以使用新的 setExact() 方法。

這種不精確的批次處理行為只適用於已更新的應用程式。如果您將 targetSdkVersion 設為「18」以下,鬧鐘在 Android 4.4 上執行時,會繼續以先前版本的行為運作。

如果應用程式使用 ContentResolver 同步處理資料...

將應用程式的 targetSdkVersion 設為「19」以上時,使用 addPeriodicSync() 建立同步作業時,系統會在預設的彈性間隔內執行同步作業,該間隔約為您指定期間的 4%。舉例來說,如果輪詢頻率為 24 小時,則同步作業可能會在每天大約 1 小時的時間範圍內執行,而不是每天在同一個時間執行。

如要為同步處理作業指定自己的彈性間隔,請開始使用新的 requestSync() 方法。詳情請參閱下文的「Sync Adapter」一節。

這項彈性間隔行為只適用於更新過的應用程式。如果您將 targetSdkVersion 設為「18」以下,在 Android 4.4 上執行時,現有的同步要求將繼續以先前版本的行為運作。

列印架構

Android 現已提供完整的架構,可讓使用者透過 Wi-Fi、藍牙或其他服務連線的印表機列印任何文件。系統會處理想要列印文件的應用程式,以及將列印工作傳送至印表機的服務之間的交易。android.print 架構會提供所有必要的 API,讓您指定要列印的文件,並將文件提交給系統進行列印。特定列印工作的實際需要 API 取決於內容。

列印一般內容

如果您想將 UI 中的內容以文件形式列印,請先建立 PrintDocumentAdapter 的子類別。您必須在這個類別中實作幾個回呼方法,包括 onLayout(),可根據提供的列印屬性建立版面配置,以及 onWrite(),可將可列印內容序列化為 ParcelFileDescriptor

如要將內容寫入 ParcelFileDescriptor,您必須傳遞 PDF。新的 PdfDocument API 提供從 getCanvas() 提供 Canvas 的便利方式,讓您在上面繪製可列印的內容。然後使用 writeTo() 方法將 PdfDocument 寫入 ParcelFileDescriptor

定義 PrintDocumentAdapter 的實作項目後,您就可以使用 PrintManager 方法 print() 執行列印作業,該方法會將 PrintDocumentAdapter 做為其中一個引數。

列印圖片

如果您只想列印相片或其他點陣圖,支援程式庫中的輔助 API 會為您完成所有工作。只要建立 PrintHelper 的新例項,使用 setScaleMode() 設定縮放模式,然後將 Bitmap 傳遞至 printBitmap() 即可。就是這麼簡單!程式庫會處理與系統的所有其他互動,將點陣圖傳送至印表機。

建構列印服務

印表機 OEM 廠商可以使用 android.printservice 架構,透過 Android 裝置與印表機提供互通性。您可以將列印服務建構及發布為 APK,讓使用者在裝置上安裝。列印服務應用程式主要會以無週邊服務的形式運作,方法是將 PrintService 類別設為子類別,接著從系統接收列印工作,並使用適當的通訊協定將工作傳送至印表機。

如要進一步瞭解如何列印應用程式內容,請參閱「列印內容」。

簡訊供應商

Telephony 內容供應器 (「簡訊供應器」) 可讓應用程式讀取及寫入裝置上的簡訊和多媒體訊息。這份報告包含簡訊和多媒體訊息的接收、草稿、傳送、待處理等狀態表格。

從 Android 4.4 開始,系統設定可讓使用者選取「預設簡訊應用程式」。選取後,只有預設的簡訊應用程式可以寫入簡訊提供者,且只有預設的簡訊應用程式會在使用者收到簡訊時收到 SMS_DELIVER_ACTION 廣播,或在使用者收到多媒體簡訊時收到 WAP_PUSH_DELIVER_ACTION 廣播。預設的訊息應用程式會在接收或傳送新訊息時,將詳細資料寫入簡訊供應器。

未選取為預設簡訊應用程式的其他應用程式只能讀取簡訊提供者,但也可以透過監聽 SMS_RECEIVED_ACTION 廣播訊息來接收新簡訊的通知。SMS_RECEIVED_ACTION 廣播訊息是無法中斷的廣播訊息,可傳送至多個應用程式。這項廣播訊息適用於未設為預設簡訊應用程式的應用程式,但需要讀取特殊的傳入訊息,例如執行電話號碼驗證。

詳情請參閱網誌文章「為 KitKat 做好 SMS 應用程式準備」。

無線和連線

主機卡片模擬

Android 應用程式現在可以模擬 ISO14443-4 (ISO-DEP) NFC 卡片,這些卡片會使用 APDU 進行資料交換 (如 ISO7816-4 所述)。這可讓搭載 Android 4.4 且支援 NFC 的裝置同時模擬多張 NFC 卡,並讓 NFC 付款終端機或其他 NFC 讀卡機根據應用程式 ID (AID) 使用適當的 NFC 卡啟動交易。

如果您想模擬在應用程式中使用這些通訊協定的 NFC 卡片,請根據 HostApduService 類別建立服務元件。相反地,如果應用程式使用安全元件模擬卡片,則需要建立以 OffHostApduService 類別為基礎的服務,該服務不會直接參與交易,但必須註冊安全元件應處理的 AID。

詳情請參閱NFC 卡模擬指南。

NFC 讀取器模式

新的 NFC 讀取器模式可讓活動限制所有 NFC 活動,只讀取活動在前景執行時感興趣的代碼類型。您可以使用 enableReaderMode() 為活動啟用閱讀器模式,提供 NfcAdapter.ReaderCallback 的實作項目,在偵測到新標記時接收回呼。

這項新功能與主機卡模擬功能搭配使用,可讓 Android 在行動支付介面的兩端運作:一個裝置可做為付款終端機 (執行讀取器模式活動的裝置),另一個裝置則可做為付款用戶端 (模擬 NFC 卡的裝置)。

紅外線發射器

在裝置上執行時,如果裝置含有紅外線 (IR) 發射器,您現在可以使用 ConsumerIrManager API 傳送 IR 訊號。如要取得 ConsumerIrManager 的例項,請使用 CONSUMER_IR_SERVICE 做為引數呼叫 getSystemService()。接著,您可以使用 getCarrierFrequencies() 查詢裝置支援的紅外線頻率,並透過 transmit() 傳遞所需的頻率和信號模式。

您應該一律先透過呼叫 hasIrEmitter() 檢查裝置是否含有紅外線發射器,但如果您的應用程式只與含有紅外線發射器的裝置相容,則應在 "android.hardware.consumerir" (FEATURE_CONSUMER_IR) 的資訊清單中加入 <uses-feature> 元素。

多媒體

自適應播放

MediaCodec API 現已支援自適應影片播放功能,可在播放期間無縫變更 Surface 的解析度,讓您可以為解碼器輸入新解析度的影格,並在輸出緩衝區變更解析度時,不必等待太久。

您可以將兩個索引鍵新增至 MediaFormat,指定應用程式需要的編解碼最大解析度:KEY_MAX_WIDTHKEY_MAX_HEIGHT。將這些項目新增至 MediaFormat 後,請使用 configure()MediaFormat 傳遞至 MediaCodec 例項。

編解碼器會在解析度相同或小於這些值的情況下,以無縫的方式進行轉換。編解碼器也可能支援大於指定上限的解析度 (只要在支援的設定檔限制範圍內),但轉換為更高解析度的畫面可能無法順暢。

如要在解碼 H.264 影片時變更解析度,請繼續使用 MediaCodec.queueInputBuffer() 將影格排入佇列,但請務必在單一緩衝區中提供新的序列參數集 (SPS) 和影像參數集 (PPS) 值,以及即時解碼器重新整理 (IDR) 影格。

不過,在嘗試設定編解碼以便進行自適應播放之前,您必須使用 FEATURE_AdaptivePlayback 呼叫 isFeatureSupported(String),確認裝置支援自適應播放功能。

注意:適應式播放功能的支援情況因廠商而異。某些編解碼可能需要更多記憶體來處理較大的解析度提示。因此,您應根據要解碼的來源素材設定解析度上限。

隨選音訊時間戳記

為方便音訊/影像同步,新的 AudioTimestamp 類別會提供 AudioTrack 處理的音訊串流中特定「影格」的時間軸詳細資料。如要取得最新的時間戳記,請將 AudioTimestamp 物件例項化,並將其傳遞至 getTimestamp()。如果時間戳記要求成功,AudioTrack 例項會填入影格單位中的一個位置,以及該影格顯示或已提交顯示的預估時間。

您可以使用 AudioTimestampnanoTime 的值 (單調),找出與 framePosition 最接近的相關影片影格,以便刪除、複製或插補影片影格,以符合音訊。或者,您也可以判斷 nanoTime 的值與未來影片影格預期時間 (並考量取樣率) 之間的差異時間,藉此預測哪個音訊影格會與影片影格同時出現。

表面圖片讀取器

新的 ImageReader API 可讓您直接存取圖片緩衝區,因為這些緩衝區會轉譯為 Surface。您可以使用靜態方法 newInstance() 取得 ImageReader。接著,請呼叫 getSurface() 來建立新的 Surface,並透過 MediaPlayerMediaCodec 等產生器提供圖片資料。如要在表面提供新圖片時收到通知,請實作 ImageReader.OnImageAvailableListener 介面,並使用 setOnImageAvailableListener() 註冊。

如今,當您將內容繪製至 Surface 時,ImageReader.OnImageAvailableListener 會在每個新圖片影格可用時接收對 onImageAvailable() 的呼叫,並提供對應的 ImageReader。您可以使用 ImageReader 呼叫 acquireLatestImage()acquireNextImage(),以 Image 物件的形式取得影格圖片資料。

Image 物件可讓您直接存取 ByteBuffer 中的圖片時間戳記、格式、尺寸和像素資料。不過,為了讓 Image 類別解讀圖片,圖片必須採用 ImageFormatPixelFormat 中常數定義的其中一種類型格式。

峰值和 RMS 測量

您現在可以建立新的 Visualizer.MeasurementPeakRms 例項,並將其傳遞至 getMeasurementPeakRms(),藉此從 Visualizer 查詢目前音訊串流的峰值和 RMS。呼叫此方法時,系統會將指定 Visualizer.MeasurementPeakRms 的峰值和 RMS 值設為最新的測量值。

音量增強

LoudnessEnhancerAudioEffect 的新子類別,可讓您提高 MediaPlayerAudioTrack 的音量。這項功能與上述新的 getMeasurementPeakRms() 方法搭配使用時特別實用,可在播放其他媒體時提高語音音軌的音量。

遙控器

Android 4.0 (API 級別 14) 推出了 RemoteControlClient API,可讓媒體應用程式使用遠端用戶端的媒體控制器事件,例如螢幕鎖定畫面上的媒體控制項。有了新的 RemoteController API,您可以自行建構遠端控制器,進而建立創新的應用程式和周邊裝置,用於控制已整合 RemoteControlClient 的任何媒體應用程式播放內容。

如要建構遙控器,您可以以任何方式實作使用者介面,但如要將媒體按鈕事件傳送至使用者的媒體應用程式,您必須建立可擴充 NotificationListenerService 類別並實作 RemoteController.OnClientUpdateListener 介面的服務。使用 NotificationListenerService 做為基礎非常重要,因為它提供適當的隱私權限制,要求使用者在系統安全性設定中,將您的應用程式設為通知事件監聽器。

NotificationListenerService 類別包含您必須實作的幾個抽象方法,但如果您只關心用於處理媒體播放的媒體控制器事件,可以將這些實作項目留空,改為專注於 RemoteController.OnClientUpdateListener 方法。

遙控器評分

Android 4.4 可讓使用者透過遙控器評分目前的曲目,這項功能是建立在遙控器用戶端 (透過 RemoteControlClient 接收媒體控制事件的應用程式) 現有功能之上。

新的 Rating 類別會封裝使用者評分的相關資訊。評分會根據評分樣式 (RATING_HEARTRATING_THUMB_UP_DOWNRATING_3_STARSRATING_4_STARSRATING_5_STARSRATING_PERCENTAGE) 和該樣式適用的評分值而定。

如要讓使用者透過遙控器評分曲目,請按照下列步驟操作:

如要在使用者透過遙控器變更評分時接收回呼,請實作新的 RemoteControlClient.OnMetadataUpdateListener 介面,並將例項傳遞至 setMetadataUpdateListener()。當使用者變更評分時,您的 RemoteControlClient.OnMetadataUpdateListener 會收到對 onMetadataUpdate() 的呼叫,並將 RATING_KEY_BY_USER 做為鍵,將 Rating 物件做為值。

隱藏式輔助字幕

VideoView現在支援在播放 HTTP 即時串流 (HLS) 影片時使用 WebVTT 字幕音軌,並根據使用者在系統設定中定義的隱藏式輔助字幕偏好設定,顯示字幕音軌。

您也可以使用 addSubtitleSource() 方法,為 WebVTT 字幕軌道提供 VideoView。這個方法會接受攜帶字幕資料的 InputStream,以及指定字幕資料格式的 MediaFormat 物件,您可以使用 createSubtitleFormat() 指定格式。系統也會根據使用者的偏好設定,在影片上方顯示這些字幕。

如果您未使用 VideoView 顯示影片內容,應盡可能讓字幕疊加層與使用者的隱藏式輔助字幕偏好設定相符。您可以使用新的 CaptioningManager API 查詢使用者的隱藏式輔助字幕偏好設定,包括 CaptioningManager.CaptionStyle 定義的樣式,例如字體和顏色。如果使用者在影片開始播放後調整某些偏好設定,您應註冊 CaptioningManager.CaptioningChangeListener 的例項,以便在任何偏好設定變更時接收回呼,然後視需要更新字幕。

動畫與圖形

場景和轉場效果

新的 android.transition 架構提供 API,可在使用者介面的不同狀態之間提供動畫。其中一個重要功能,就是您可以為每個 UI 建立個別的版面配置,藉此定義 UI 的不同狀態 (稱為「場景」)。如要從一個場景切換至另一個場景,請執行「轉場」,系統會計算所需的動畫,將目前場景的版面配置變更為下一個場景。

如要切換兩個場景,通常需要執行以下操作:

  1. 指定包含您要變更的 UI 元件的 ViewGroup
  2. 指定代表變更 (下一個場景) 的最終版面配置。
  3. 指定應為版面配置變更設定動畫的轉場效果類型。
  4. 執行轉場效果。

您可以使用 Scene 物件完成步驟 1 和 2。Scene 包含描述版面配置屬性中繼資料,這些屬性是執行轉場時所需的,包括場景的父項檢視畫面和場景的版面配置。您可以使用類別建構函式或靜態方法 getSceneForLayout() 建立 Scene

接著,您必須使用 TransitionManager 完成步驟 3 和 4。其中一種方法是將 Scene 傳遞至靜態方法 go()。這會在目前版面配置中找出場景的父項檢視區塊,並對子項檢視區塊執行轉場,以便達到 Scene 定義的版面配置。

您也可以不建立 Scene 物件,改為呼叫 beginDelayedTransition(),指定包含您要變更的檢視畫面的 ViewGroup。接著,新增、移除或重新設定目標檢視畫面。系統視需要排版變更後,轉場效果就會開始為所有受影響的檢視畫面製作動畫。

如要進一步控管,您可以使用專案 res/transition/ 目錄中的 XML 檔案,定義預先定義場景之間應出現的轉場效果組合。在 <transitionManager> 元素中指定一或多個 <transition> 標記,每個標記都會指定一個場景 (對版面配置檔案的參照),以及進入和/或離開該場景時要套用的轉場效果。然後使用 inflateTransitionManager() 對這組轉場效果進行充氣。使用傳回的 TransitionManager 搭配 transitionTo() 執行每個轉場,並傳遞由其中一個 <transition> 標記代表的 Scene。您也可以使用 TransitionManager API 透過程式定義轉場組合。

指定轉場時,您可以使用 Transition 子類別定義的多種預先定義類型,例如 FadeChangeBounds。如果您未指定轉場類型,系統預設會使用 AutoTransition,這會視需要自動淡出、移動及調整檢視畫面大小。此外,您也可以擴充任何這些類別來建立自訂轉場效果,以便執行動畫。自訂轉場效果可追蹤您想要的任何屬性變更,並根據這些變更建立所需的動畫。舉例來說,您可以提供 Transition 的子類別,監聽檢視畫面「旋轉」屬性的變更,然後為任何變更設定動畫。

詳情請參閱 TransitionManager 說明文件。

動畫暫停

Animator API 現在可讓您使用 pause()resume() 方法暫停及繼續播放動畫。

如要追蹤動畫的狀態,您可以實作 Animator.AnimatorPauseListener 介面,該介面會在動畫暫停和繼續播放時提供回呼:pause()resume()。然後使用 addPauseListener() 將監聽器新增至 Animator 物件。

或者,您也可以為 AnimatorListenerAdapter 抽象類別建立子類別,該類別現在包含 Animator.AnimatorPauseListener 定義的暫停和繼續執行回呼的空白實作。

可重複使用的點陣圖

您現在可以重複使用 BitmapFactory 中的任何可變動點陣圖,來解碼任何其他點陣圖,即使新點陣圖的大小不同也沒關係。只要解碼點陣圖的產生位元組數 (可從 getByteCount() 取得) 小於或等於重複使用點陣圖的已配置位元組數 (可從 getAllocationByteCount() 取得),即可重複使用點陣圖。詳情請參閱 inBitmap

Bitmap 的新 API 可讓您在 BitmapFactory 以外 (手動產生位圖或自訂解碼邏輯) 重新設定類似的內容,以便重複使用。您現在可以使用 setHeight()setWidth() 方法設定位元圖的尺寸,並使用 setConfig() 指定新的 Bitmap.Config,而不會影響基礎位元圖分配。reconfigure() 方法也提供方便的方法,可透過單一呼叫將這些變更合併。

不過,您不應重新設定檢視畫面系統目前使用的位圖,因為底層像素緩衝區不會以可預測的方式重新對應。

使用者內容

儲存空間存取架構

在舊版 Android 中,如果您希望應用程式從其他應用程式擷取特定類型的檔案,則該應用程式必須使用 ACTION_GET_CONTENT 動作叫用意圖。這項動作仍是要求要匯入至應用程式的檔案的適當方式。不過,Android 4.4 推出了 ACTION_OPEN_DOCUMENT 動作,可讓使用者選取特定類型的檔案,並授予應用程式該檔案的長期讀取存取權 (可能會授予寫入存取權),而無須將檔案匯入應用程式。

如果您正在開發提供檔案儲存空間服務的應用程式 (例如雲端儲存服務),您可以將內容提供者實作為新 DocumentsProvider 類別的子類別,參與這個統一 UI 的檔案挑選功能。DocumentsProvider 的子類別必須包含可接受 PROVIDER_INTERFACE 動作 ("android.content.action.DOCUMENTS_PROVIDER") 的意圖篩選器。接著,您必須在 DocumentsProvider 中實作四個抽象方法:

queryRoots()
這個方法必須傳回 Cursor,使用 DocumentsContract.Root 中定義的資料欄描述文件儲存空間的所有根目錄。
queryChildDocuments()
這項作業必須傳回 Cursor,以 DocumentsContract.Document 中定義的資料欄,描述指定目錄中的所有檔案。
queryDocument()
這個方法必須傳回 Cursor,用於描述指定檔案,並使用 DocumentsContract.Document 中定義的資料欄。
openDocument()
這必須傳回代表指定檔案的 ParcelFileDescriptor。使用者選取檔案,且用戶端應用程式透過呼叫 openFileDescriptor() 要求存取權時,系統就會呼叫此方法。

詳情請參閱 Storage Access Framework 指南。

外部儲存空間存取權

現在您可以在次要外部儲存媒體上讀取及寫入應用程式特定檔案,例如當裝置同時提供模擬儲存空間和 SD 卡時。新的 getExternalFilesDirs() 方法與現有的 getExternalFilesDir() 方法運作方式相同,唯一的差異在於它會傳回 File 物件的陣列。在讀取或寫入此方法傳回的任何路徑之前,請將 File 物件傳遞至新的 getStorageState() 方法,以驗證目前可用的儲存空間。

存取應用程式專屬快取目錄和 OBB 目錄的其他方法,現在也有對應的版本可提供次要儲存裝置存取權:分別為 getExternalCacheDirs()getObbDirs()

系統會將傳回的 File 陣列中的第一個項目視為裝置的主要外部儲存空間,這與 getExternalFilesDir() 等現有方法傳回的 File 相同。

注意:自 Android 4.4 起,如果您只需要透過上述方法存取外部儲存空間中的應用程式專屬區域,平台不再要求應用程式取得 WRITE_EXTERNAL_STORAGEREAD_EXTERNAL_STORAGE。不過,如果您想存取 getExternalStoragePublicDirectory() 提供的外部儲存空間可共用區域,就必須具備這些權限。

同步轉換介面

ContentResolver 中的新 requestSync() 方法可簡化為 ContentProvider 定義同步處理要求的部分程序,方法是將要求封裝在新的 SyncRequest 物件中,您可以使用 SyncRequest.Builder 建立這類物件。SyncRequest 中的屬性提供與現有 ContentProvider 同步呼叫相同的功能,但透過啟用 setDisallowMetered(),可指定在網路受到計量時應捨棄同步作業。

使用者輸入內容

新的感應器類型

新的 TYPE_GEOMAGNETIC_ROTATION_VECTOR 感應器會根據磁力計提供旋轉向量資料,在沒有陀螺儀或搭配批次感應器事件記錄手機休眠時的方向時,這會是 TYPE_ROTATION_VECTOR 感應器的實用替代方案。這個感應器的耗電量比 TYPE_ROTATION_VECTOR 低,但可能會產生雜訊事件資料,且在使用者處於戶外時最有效。

Android 也支援硬體內建的步數感應器:

TYPE_STEP_DETECTOR
每當使用者走一步,這個感應器就會觸發事件。每當使用者踏出一步時,這個感應器就會傳送一個事件,其中的值為 1.0,並附上表示步驟發生時間的時間戳記。
TYPE_STEP_COUNTER
這個感應器也會在偵測到每個步數時觸發事件,但會傳送自應用程式首次註冊這個感應器以來的累積步數。

請注意,這兩個步數感應器不一定會產生相同的結果。TYPE_STEP_COUNTER 事件的延遲時間比 TYPE_STEP_DETECTOR 事件長,這是因為 TYPE_STEP_COUNTER 演算法需要進行更多處理,才能排除偽陽性。因此,TYPE_STEP_COUNTER 可能會較慢地提交事件,但結果應該會更準確。

這兩種步數感應器都會依硬體而異 (Nexus 5 是第一款支援這類感應器的裝置),因此您應使用 FEATURE_SENSOR_STEP_DETECTORFEATURE_SENSOR_STEP_COUNTER 常數,透過 hasSystemFeature() 檢查感應器是否可用。

感應器事件批次處理

為更妥善管理裝置電力,SensorManager API 現可讓您指定系統向應用程式傳送批次感應器事件的頻率。這不會減少應用程式在特定時間內可用的實際感應器事件數量,而是減少系統以感應器更新方式呼叫 SensorEventListener 的頻率。也就是說,系統不會在事件發生的當下就將事件傳送到應用程式,而是會儲存一段時間內發生的所有事件,然後一次傳送到應用程式。

為提供批次處理功能,SensorManager 類別新增了兩個 registerListener() 方法,可讓您指定「最大報表延遲時間」。這個新參數可指定 SensorEventListener 在傳送新感應器事件時,可容許的最大延遲時間。舉例來說,如果您指定批次延遲時間為一分鐘,系統會以不超過一分鐘的間隔,連續呼叫 onSensorChanged() 方法 (每個已分批處理的事件各一次),傳送最近的批次事件組合。感應器事件的延遲時間絕不會超過最大回報延遲時間值,但如果其他應用程式已要求相同感應器的延遲時間縮短,則可能會提早到達。

不過,請注意,感應器會根據回報延遲時間,僅在 CPU 處於喚醒狀態時,將批次事件傳送至應用程式。雖然支援批次處理的硬體感應器會在 CPU 休眠時繼續收集感應器事件,但不會喚醒 CPU 來將批次事件傳送至應用程式。當感應器的事件記憶體用盡時,就會開始捨棄最舊的事件,以便儲存最新的事件。您可以避免遺失事件,方法是在感應器填滿記憶體之前喚醒裝置,然後呼叫 flush() 擷取最新一批事件。如要預估記憶體何時會滿載並應清除,請呼叫 getFifoMaxEventCount() 取得可儲存的最大感應器事件數量,然後將該數字除以應用程式需要的每個事件速率。使用該計算結果,透過 AlarmManager 設定喚醒鬧鐘,叫用 Service (實作 SensorEventListener) 來清除感應器。

注意:並非所有裝置都支援感應器事件批次處理功能,因為這項功能需要硬體感應器的支援。不過,從 Android 4.4 開始,您應一律使用新的 registerListener() 方法,因為如果裝置不支援批次處理,系統會優雅地忽略批次延遲引數,並即時傳送感應器事件。

控制器身分

Android 會使用獨特的整數來識別每個已連結的控制器,您可以使用 getControllerNumber() 查詢這類整數,方便將每個控制器與遊戲中的不同玩家建立關聯。每個控制器的編號可能會因控制器的連線狀態、使用者重新設定控制器或其他因素而變更,因此您應註冊 InputManager.InputDeviceListener 的例項,以便追蹤每個輸入裝置對應的控制器編號。然後在變更發生時,為每個 InputDevice 呼叫 getControllerNumber()

連線裝置現在也會提供產品和供應商 ID,可透過 getProductId()getVendorId() 取得。如果您需要根據裝置上可用的按鍵組修改按鍵對應項目,可以使用 hasKeys(int...) 查詢裝置,確認是否可使用特定按鍵。

使用者介面

沉浸式全螢幕模式

如要為應用程式提供可填滿整個螢幕的版面配置,setSystemUiVisibility() 的新 SYSTEM_UI_FLAG_IMMERSIVE 標記 (與 SYSTEM_UI_FLAG_HIDE_NAVIGATION 搭配使用時) 可啟用新的沉浸式全螢幕模式。啟用沉浸式全螢幕模式時,活動會繼續接收所有觸控事件。使用者可以沿著系統資訊列通常顯示的區域,向內滑動,即可顯示系統資訊列。這會清除 SYSTEM_UI_FLAG_HIDE_NAVIGATION 標記 (以及已套用的 SYSTEM_UI_FLAG_FULLSCREEN 標記),讓系統資訊列持續顯示。不過,如果您希望系統列在幾秒後再次隱藏,可以改用 SYSTEM_UI_FLAG_IMMERSIVE_STICKY 標記。

半透明系統資訊列

您現在可以使用新的主題 Theme.Holo.NoActionBar.TranslucentDecorTheme.Holo.Light.NoActionBar.TranslucentDecor,讓系統列變成部分半透明。啟用半透明系統資訊列後,版面配置會填滿系統資訊列後方的區域,因此您必須為版面配置中不應受系統資訊列覆蓋的部分啟用 fitsSystemWindows

如果您要建立自訂主題,請將其中一個主題設為父項主題,或是在主題中加入 windowTranslucentNavigationwindowTranslucentStatus 樣式屬性。

強化版通知接聽器

Android 4.3 新增了 NotificationListenerService API,讓應用程式在系統發布新通知時,接收相關資訊。在 Android 4.4 中,通知事件監聽器可以擷取通知的其他中繼資料,以及通知動作的完整詳細資料:

新的 Notification.extras 欄位包含 Bundle,可為通知建構工具提供額外中繼資料,例如 EXTRA_TITLEEXTRA_PICTURE。新的 Notification.Action 類別會定義附加至通知的動作特徵,您可以從新的 actions 欄位擷取這些特徵。

針對 RTL 版面配置使用可繪項目鏡像功能

在舊版 Android 上,如果應用程式包含應將水平方向反轉為由右至左版面配置的圖片,您必須在 drawables-ldrtl/ 資源目錄中加入鏡像圖片。只要在可繪資源上啟用 autoMirrored 屬性,或呼叫 setAutoMirrored(),系統就能自動鏡射圖片。啟用後,當版面配置方向從右到左時,系統會自動鏡像 Drawable

無障礙設定

View 類別現在可讓您在 XML 版面配置中新增 accessibilityLiveRegion 屬性,或呼叫 setAccessibilityLiveRegion(),為使用新文字內容動態更新的 UI 部分宣告「即時區域」。舉例來說,如果登入畫面中的文字欄位顯示「密碼不正確」通知,應標示為即時區域,這樣螢幕閱讀器就會在訊息變更時朗讀。

提供無障礙服務的應用程式現在也可以透過新的 API 增強功能,這些 API 可提供有關使用 AccessibilityNodeInfo.CollectionInfoAccessibilityNodeInfo.CollectionItemInfo 的清單或格狀檢視畫面等檢視畫面集合的資訊。

應用程式權限

以下是應用程式必須使用 <uses-permission> 標記要求的新權限,才能使用特定的新 API:

INSTALL_SHORTCUT
允許應用程式在啟動器中安裝捷徑
UNINSTALL_SHORTCUT
允許應用程式在啟動器中解除安裝捷徑
TRANSMIT_IR
允許應用程式使用裝置的紅外線發射器 (如有)

注意:自 Android 4.4 起,如果您想使用 getExternalFilesDir() 等方法存取外部儲存空間的應用程式專屬區域,平台不再要求應用程式取得 WRITE_EXTERNAL_STORAGEREAD_EXTERNAL_STORAGE。不過,如果您想存取 getExternalStoragePublicDirectory() 提供的外部儲存空間可共用區域,仍需要這些權限。

裝置功能

以下是您可以使用 <uses-feature> 標記宣告的新裝置功能,以便宣告應用程式需求,並在 Google Play 上啟用篩選功能,或在執行階段進行檢查:

FEATURE_CONSUMER_IR
裝置可與消費性紅外線裝置通訊。
FEATURE_DEVICE_ADMIN
裝置支援透過裝置管理員強制執行裝置政策。
FEATURE_NFC_HOST_CARD_EMULATION
裝置支援主機型 NFC 卡模擬功能。
FEATURE_SENSOR_STEP_COUNTER
裝置內建硬體計步器。
FEATURE_SENSOR_STEP_DETECTOR
裝置內建硬體步測器。

如需 Android 4.4 中所有 API 異動內容的詳細資訊,請參閱 API 差異比較表