Android 4.2 API

API 級別:17

Android 4.2 (JELLY_BEAN_MR1) 是 Jelly Bean 的更新版本,為使用者和應用程式提供新功能 開發人員。本文件將介紹 實用的新 API

應用程式開發人員應前往下列連結下載 Android 4.2 系統映像檔和 SDK 平台: SDK Manager。如果發生以下情況: 沒有搭載 Android 4.2 的裝置可以測試應用程式,請使用 Android 4.2 系統 使用 Android Emulator 測試應用程式的映像檔。 然後,針對 Android 4.2 平台建構應用程式,開始使用最新的 API。

為了針對搭載 Android 4.2 的裝置進一步最佳化應用程式, 請將 targetSdkVersion 設為 "17",安裝在 Android 4.2 系統映像檔上 ,然後使用這項變更發布更新。

個人中心 可以使用 Android 4.2 中的 API,同時透過新增 條件,在執行前檢查系統 API 級別 minSdkVersion 不支援的 API。 如要進一步瞭解 請參閱建立回溯相容 UI

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

重要行為變更

如果您先前曾發布 Android 應用程式,請注意下列事項 可能影響應用程式行為的變更:

  • 在預設情況下,我們已不再匯出內容供應器,也就是說,使用預設值 的 android:exported 屬性現在是 “false"。如果有其他應用程式必須 可存取內容供應器,您必須立即明確設定 android:exported="true"

    您必須將 android:targetSdkVersionandroid:minSdkVersion 設為 17 以上,這項變更才會生效。否則,預設值仍為 “true" 甚至能在 Android 4.2 以上版本中執行

  • 與舊版 Android 相比,使用者位置結果的準確度可能會降低 但若應用程式要求 ACCESS_COARSE_LOCATION 權限,但 不會要求 ACCESS_FINE_LOCATION 權限。

    讓應用程式要求下列權限時,能滿足使用者的隱私權期望 概略位置 (而非精確位置),系統將不會提供使用者位置預估值 比城市街區更準確

  • Settings.System 定義的部分裝置設定現已 唯讀。如果應用程式嘗試寫入已移至 Settings.GlobalSettings.System 中定義的設定, 在 Android 4.2 以上版本執行時,寫入作業會自動失敗,不顯示任何訊息。

    即使 android:targetSdkVersionandroid:minSdkVersion 的值低於 17,應用程式也無法修改 已移至 Settings.Global

  • 如果您的應用程式使用 WebView,Android 4.2 會為 安全,以便您可以放心將 JavaScript 繫結至 Android 程式碼。如果您將 targetSdkVersion敬上 至 17 以上版本,您現在需要將 @JavascriptInterface 註解新增至 可讓您的 JavaScript 使用 (方法也必須設為公開)。如未提供 備註,WebView 中的網頁無法透過該方法存取 可在 Android 4.2 以上版本中執行如果將 targetSdkVersion敬上 16 以下,並不需要註解,但我們建議您更新目標版本 並添加備註來加強安全防護

    進一步瞭解繫結 匯入 Android 程式碼

Daydream

Daydream 是適用於 Android 裝置的全新互動式螢幕保護程式模式。裝置會自動啟動 裝置插入座架,或裝置在接上電源時處於閒置狀態時 充電器 (而非關閉螢幕)。Daydream 一次展示一個夢想, 純粹是視覺、被動式螢幕,會在使用者輕觸時關閉,或具有互動性和回應性 完整的輸入事件套件您的夢想會在應用程式程序中運作,並且具備 Android UI 工具包,包括檢視區塊、版面配置和動畫,因此變得更加靈活, 功能比動態桌布或應用程式小工具更強大

實作 DreamService 的子類別即可建立 Daydream 的夢。DreamService API 採用 和 Activity 的相似設計。如要為 然後,將版面配置資源 ID 或 View 傳遞至 setContentView() 視窗,例如 onAttachedToWindow() 回呼。

DreamService 類別提供其他重要生命週期回呼 方法,例如 onDreamingStarted()onDreamingStopped()onDetachedFromWindow()Service 您無法透過以下位置啟動DreamService: 應用程式,因為系統會自動啟動。

如果你的夢想是互動,可以從夢想開始活動,並引導使用者前往 應用程式的完整使用者介面,提供更多詳細資訊或控制項。您可以使用 finish() 結束夢,讓使用者能夠看到 新的活動。

若要允許系統取得您的 day 天 ,請使用 <service> 元素宣告 DreamService 。然後,您必須加入含有 "android.service.dreams.DreamService" 動作的意圖篩選器。例如:

<service android:name=".MyDream" android:exported="true"
    android:icon="@drawable/dream_icon" android:label="@string/dream_label" >
    <intent-filter>
        <action android:name="android.service.dreams.DreamService" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</service>

DreamService 中還有其他實用方法 請留意以下事項:

  • setInteractive(boolean) 可控管是否要 但是,夢想會在使用者輸入時立即收到輸入事件或離開。如果夢想 互動,使用者可使用 [Back] (返回) 或 [Home] (主畫面) 按鈕離開夢想,或直接呼叫 finish() 就能阻止夢境。
  • 如要使用完全沈浸式螢幕,可以呼叫 setFullscreen() 來隱藏狀態列。
  • 在 Daydream 啟動前,螢幕會變暗,通知使用者閒置逾時 接近中。呼叫 setScreenBright(true) 可改將螢幕設為一般亮度。

詳情請參閱 DreamService 說明文件。

第二螢幕

Android 現在可讓應用程式在連接的其他裝置上顯示獨創內容 透過有線連線或 Wi-Fi 連線至使用者的裝置。 如要為次要螢幕建立獨特內容,請擴充 Presentation 並實作 onCreate() 回呼。在特定時間範圍內 onCreate(),指定次要螢幕的 UI 呼叫 setContentView()Presentation 類別是 Dialog 類別的擴充,提供應用程式可在哪個區域顯示專屬 UI 次要螢幕。

如要偵測可顯示 Presentation 的次要螢幕,請按照下列步驟操作: 請使用 DisplayManagerMediaRouter 相互整合雖然 DisplayManager API 可讓您列舉 可能會同時連線的多個螢幕,通常應該改用 MediaRouter,以便快速存取系統的預設螢幕 簡報

如要取得簡報的預設顯示畫面,請呼叫 MediaRouter.getSelectedRoute() 並傳遞 ROUTE_TYPE_LIVE_VIDEO。這會傳回 MediaRouter.RouteInfo 物件,說明系統目前選取的路徑 影音簡報如果 MediaRouter.RouteInfo 不是空值,請呼叫 getPresentationDisplay() 以取得代表已連結螢幕的 Display

接著,您可以傳遞 Display 物件來顯示簡報 加入 Presentation 類別的建構函式。你分享的螢幕畫面將立即顯示 就會顯示在次要顯示器上

如要在執行階段偵測到新螢幕連線時進行偵測,請建立 MediaRouter.SimpleCallback 的執行個體,並在當中實作 onRoutePresentationDisplayChanged() 回呼方法,系統會在新螢幕連線時呼叫該方法 連接簡報畫面。然後,將 MediaRouter.SimpleCallbackROUTE_TYPE_LIVE_VIDEO 路線類型傳遞至 MediaRouter.addCallback(),以註冊 MediaRouter.SimpleCallback。當您接到: onRoutePresentationDisplayChanged() 只需按照上述方式呼叫 MediaRouter.getSelectedRoute() 即可。

如要進一步最佳化 Presentation 中的 UI, 第二螢幕 指定不同主題,方法是在已顯示的 <style> 中指定 android:presentationTheme 屬性 套用到您的應用程式或活動。

提醒您,使用者裝置所連結的螢幕通常較大 代表的轉換率可能與螢幕密度不同裝置螢幕特性可能會有所不同 提供專為這類大螢幕最佳化的資源。如果需要 如要從 Presentation 要求其他資源,請呼叫 getContext().getResources() 以取得與螢幕對應的 Resources 物件。這麼做可 在應用程式中找出最適合的 次要螢幕的螢幕大小和密度

如需更多資訊和部分程式碼範例,請參閱 Presentation 類別說明文件

螢幕鎖定小工具

Android 現在允許使用者在螢幕鎖定畫面上新增應用程式小工具。如要讓您的應用程式小工具在 螢幕鎖定,請將 android:widgetCategory 屬性新增至指定 AppWidgetProviderInfo 的 XML 檔案。這項屬性支援兩個值:home_screenkeyguard。屬性預設為 home_screen,方便使用者 應用程式小工具。如果您希望應用程式小工具也能同時顯示在鎖定畫面上 畫面中新增 keyguard 值:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:widgetCategory="keyguard|home_screen">
</appwidget-provider>

您也應該在螢幕鎖定畫面上,為應用程式小工具指定初始版面配置,方法是使用 android:initialKeyguardLayout 屬性。運作方式與 android:initialLayout 相同,只要由該程式碼提供 可以立即顯示的版面配置,直到應用程式小工具初始化且能夠更新 版面配置。

進一步瞭解如何建構適用於螢幕鎖定畫面的應用程式小工具,包括如何 在螢幕鎖定畫面調整應用程式小工具的大小,請參閱「應用程式小工具」指南。

多位使用者

Android 現在允許在平板電腦等共用裝置中使用多個使用者空間。每個 裝置擁有一組專屬帳戶、應用程式、系統設定、檔案和任何其他設定 使用者相關資料。

應用程式開發人員不必採取其他行動,就能讓應用程式正常運作。 方便多位使用者共用同一個裝置無論有多少使用者在 裝置時,應用程式為特定使用者儲存的資料會與應用程式儲存的資料分開儲存 讓使用者享有更便利的體驗系統會追蹤哪些使用者資料屬於使用者程序 應用程式正在運作,且僅允許應用程式存取該使用者的資料,而且不允許 存取其他使用者的資料。

在多使用者環境中儲存資料

每當您的應用程式儲存使用者的偏好設定、建立資料庫,或將檔案寫入使用者的 內部或外部儲存空間,只有在該使用者身分執行時,才能存取該資料。

如要確定您的應用程式在多使用者環境中能正常運作,請不要參考 使用硬式編碼路徑,並一律使用內部應用程式目錄或外部儲存空間位置 適當的 API:

無論您使用哪一個 API 來儲存特定使用者的資料, 能以不同的使用者身分執行從應用程式的角度來看,每位使用者都在運作中 並在完全獨立的裝置上運作

在多使用者環境中辨識使用者

如果您的應用程式想識別不重複使用者,例如收集數據分析或建立其他帳戶 連結,請遵循辨識 不重複安裝請在下列應用程式的啟動階段啟動時建立新的 UUID: 初次追蹤使用者時,無論有多少人,您都必須取得追蹤每位使用者的專屬 ID 使用者在單一裝置上安裝您的應用程式。或者,您也可以儲存從 伺服器或使用 Google 雲端通訊提供的註冊 ID。

請注意,如果應用程式要求提供任一硬體裝置 ID (例如 Wi-Fi MAC) 地址或 SERIAL 數字) 就會為每個 Pod 提供相同的值 因為這類 ID 與硬體而非使用者相關聯。其他 上述 ID 的識別 應用程式安裝網誌文章。

新版通用設定

系統設定已更新,現在新增 Settings.Global,可支援多位使用者。這組設定與 Settings.Secure 設定類似,因為這些設定處於唯讀狀態,但會套用至以下位置: 裝置上所有使用者空間。

系統將從「Settings.System」或「Settings.Secure」將多項現有設定移到此處。如果您的應用程式是 目前正在變更 Settings.System 中定義的設定 (例如 AIRPLANE_MODE_ON), 在執行 Android 4.2 以上版本的裝置上,如果這些設定 已移至 Settings.Global。您可以繼續讀取 Settings.Global,但由於設定不再安全, 在應用程式變更時,嘗試這麼做將會失敗,而且系統會對 在 Android 4.2 以上版本執行應用程式時,系統會記錄應用程式。

支援 RTL 版面配置

Android 現在提供多個 API,可讓您妥善建構使用者介面 轉換版面配置方向,支援使用從右到左 (RTL) UI 和朗讀的語言 例如阿拉伯文和希伯來文

如要開始在應用程式中支援 RTL 版面配置,請將 android:supportsRtl 屬性設為資訊清單檔案中的 <application> 元素 並設定 “true"。啟用後,系統會啟用各種 RTL API, 以 RTL 版面配置顯示應用程式。舉例來說,動作列會顯示圖示和標題 ,以及您使用 架構提供的 View 類別也會復原。

如果需要進一步最佳化使用 RTL 版面配置顯示的應用程式外觀, 最佳化有兩種基本層級:

  1. 將左右方向的版面配置屬性轉換為開始及結束方向的版面配置 資源。

    例如,使用 android:layout_marginStart 取代 android:layout_marginLeftandroid:layout_marginEnd,取代 android:layout_marginRight

    RelativeLayout 類別也會提供對應的版面配置 取代左側/右側位置的屬性,例如將 android:layout_alignParentStart 取代為 以 android:layout_alignParentLeftandroid:layout_toStartOf 取代 android:layout_toLeftOf

  2. 如要全面最佳化 RTL 版面配置,您可以提供完全獨立的 使用 ldrtl 資源限定詞的版面配置檔案 (ldrtl 代表 layout-direction-right-to-left}。舉例來說,您可以將預設版面配置檔案儲存在 res/layout/res/layout-ldrtl/ 中的 RTL 最佳化版面配置。

    ldrtl 限定詞非常適合可繪製資源,因此您可以提供 指向對應閱讀方向的方向圖形。

架構中還提供許多其他用來支援 RTL 版面配置的 API,例如 View 類別,讓您可以實作適用於自訂內容的正確行為 以及在 Configuration 中查詢目前的版面配置方向。

注意:如果您使用 SQlite,且資料表或資料欄的名稱, 「僅限數字」成為 注意:使用 String.format(String, Object...) 可能導致號碼發生錯誤 已轉換成阿拉伯文版本 (如果裝置已設定為阿拉伯文語言代碼)。 您必須使用 String.format(Locale,String,Object...) 確保數字為 而是以 ASCII 形式保留。您也可以使用 String.format("%d", int),而不要使用 String.valueOf(int): 以便設定數字格式

巢狀片段

您現在可以在片段中嵌入片段。這在各種情況下都很實用 ,您希望將動態且可重複使用的 UI 元件放入 UI 元件 動態且可重複使用舉例來說,如果您使用 ViewPager 建立可左右滑動並耗用大部分螢幕空間的片段,您可以 現在可以將片段插入每個片段頁面。

若要為片段建立巢狀結構,只要呼叫 getChildFragmentManager() 上的 您要新增片段的 Fragment。系統會傳回 FragmentManager,您也可以像在頂層活動中一樣使用 建立片段交易例如,以下程式碼可將 現有的 Fragment 類別:

Kotlin

val videoFragment = VideoPlayerFragment()
childFragmentManager.beginTransaction().apply {
    add(R.id.video_fragment, videoFragment)
    commit()
}

Java

Fragment videoFragment = new VideoPlayerFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.video_fragment, videoFragment).commit();

在巢狀片段中,您可以透過呼叫 getParentFragment()

Android 支援資料庫現在也支援巢狀片段,方便您導入巢狀結構片段 Android 1.6 以上版本的片段設計。

注意:如果版面配置正在加載版面配置,則無法加載至片段 包含 <fragment>。只有在新增至 片段。

RenderScript

強化了 Renderscript 運算功能,並包含下列功能:

指令碼內建函式

您可以使用 Renderscript 的內建指令碼內建函式 執行以下作業:

如要使用指令碼內建函式,請呼叫每種方法的靜態 create() 方法 建立指令碼執行個體。接著,您就能呼叫可用的 set() 方法,設定任何必要的輸入和選項。 最後,呼叫 forEach() 方法來執行指令碼。

指令碼群組

ScriptGroup 可讓您將相關的 Renderscript 鏈結在一起 編寫指令碼,然後按一下呼叫來執行

使用 ScriptGroup.Builder 將所有指令碼新增至群組 呼叫 addKernel()。當您 加入所有指令碼,在 呼叫 addConnection() 來編寫指令碼。 新增連結後,請呼叫 create() 即可建立指令碼群組。在執行指令碼群組前,請先指定輸入內容 Allocation 和初始指令碼,以便與 setInput(Script.KernelID, Allocation) 方法,並提供輸出內容 Allocation,其中會寫入結果,並將結果寫入最終指令碼 搭配 setOutput() 執行最後,呼叫 execute():執行指令碼群組。

FilterScript

Filterscript 定義現有 Renderscript API 的限制,允許執行產生的程式碼 可在多種處理器 (CPU、GPU 和 DSP) 上使用如要建立 Filterscript 檔案,請建立 .fs 檔案取代 .rs 檔案並指定 #pragma rs_fp_relaxed 即可 告知 Renderscript 執行階段,指令碼不需要嚴格的 IEEE 754-2008 浮點精確度。 這種精度允許將非正規數清除至零,以及朝零捨去。此外,您的 Filterscript 指令碼不得使用 32 位元內建型別,且必須使用 __attribute__((kernel)) 屬性,因為 Filterscript 不支援指標, root() 函式定義的預設簽章。

注意:雖然 Filterscript 支援平台,但開發人員 SDK 工具版本 21.0.1 將提供支援。

如需 Android 4.2 所有 API 變更的詳細檢視畫面,請參閱 API 差異報告