API 級別:18
Android 4.3 (JELLY_BEAN_MR2
)
是 Jelly Bean 的更新版本,為使用者和應用程式提供新功能
開發人員。本文件將介紹
新的 API
應用程式開發人員應下載 Android 4.3 系統映像檔 和 SDK 平台 (由 SDK Manager 提供) 若您的裝置搭載 Android 4.3, 請使用 Android 4.3 系統測試應用程式 使用 Android Emulator 測試應用程式的映像檔。 然後用 Android 4.3 平台建構應用程式 最新的 API
更新目標 API 級別
為了針對搭載 Android 4.3 的裝置進一步最佳化應用程式,
請將 targetSdkVersion
設為
"18"
,安裝在 Android 4.3 系統映像檔上
,然後使用這項變更發布更新。
您可以在 Android 4.3 中使用 API,同時支援較舊版本,方法是新增
條件,在執行前檢查系統 API 級別
minSdkVersion
不支援的 API。
若要進一步瞭解如何維持回溯相容性,請參閱支援不同之處
平台版本。
Android 支援資料庫中也提供各式各樣的 API,方便您實作 新功能。
如要進一步瞭解 API 級別的運作方式,請參閱「什麼是 API? 關卡?
重要行為變更
如果您先前曾發布 Android 應用程式,請注意,您的應用程式可能會 受到 Android 4.3 變更的影響
如果您的應用程式使用隱含意圖...
應用程式可能在設有限制的設定檔環境中運作。
設有限制的設定檔環境中的使用者可能無法
但可使用所有標準 Android 應用程式舉例來說,設有限制的個人資料可能會有
網路瀏覽器和相機應用程式已停用。因此,您的應用程式不應假設
前提是你呼叫 startActivity()
驗證應用程式是否可處理 Intent
,
應用程式可能會在設有限制的設定檔中異常終止。
使用隱含意圖時,請務必呼叫 resolveActivity()
或 queryIntentActivities()
,確認應用程式是否能處理意圖。例如:
Kotlin
val intent = Intent(Intent.ACTION_SEND) ... if (intent.resolveActivity(packageManager) != null) { startActivity(intent) } else { Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show() }
Java
Intent intent = new Intent(Intent.ACTION_SEND); ... if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } else { Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show(); }
如果您的應用程式取決於帳戶...
應用程式可能在設有限制的設定檔環境中運作。
根據預設,受限設定檔環境中的使用者不具備使用者帳戶的存取權限。
如果您的應用程式依附 Account
,可能會異常終止或運作
無預期的情況
如要完全禁止設有限制的個人資料使用應用程式,是因為
應用程式需要機密帳戶資訊,請在資訊清單的 <application>
中指定 android:requiredAccountType
屬性
元素。
如果您想允許受限的設定檔繼續使用您的應用程式,即使無法這麼做 建立自己的帳戶,接著您可以停用需要有帳戶的應用程式功能 也可以允許設有限制的個人資料存取主要使用者建立的帳戶如要 如需相關資訊,請參閱 請參閱下文,瞭解如何在設有限制的設定檔中支援帳戶。
如果您的應用程式使用 VideoView...
你的影片在 Android 4.3 裝置上可能會變小。
在舊版 Android 中,VideoView
小工具有誤
計算 layout_height
和 layout_width
的 "wrap_content"
值與 "match_parent"
相同。因此,將 "wrap_content"
用於高度或寬度時,可能之前已提供您想要的影片版面配置。
在 Android 4.3 以上版本中,這可能會導致影片尺寸小得多。如要解決這個問題,請將
與 "match_parent"
一起"wrap_content"
。確認影片可在以下位置正常顯示:
Android 4.3 和較舊版本
設有限制的個人資料
在 Android 平板電腦上,使用者現在可以根據主要使用者建立設有限制的個人資料。 使用者建立設有限制的個人資料時,可以啟用一些限制,例如可執行哪些應用程式 。Android 4.3 中的一組全新 API 也可讓您建構精細的 API 對您開發的應用程式設下限制。舉例來說,您可以使用新的 API 因此,當使用者在應用程式的運作時, 受限設定檔環境。
使用者用來控制您建立的限制的 UI 是由系統的
「設定」應用程式。如要讓使用者看到應用程式的限制設定,請按照下列步驟操作:
您必須建立接收 ACTION_GET_RESTRICTION_ENTRIES
意圖的 BroadcastReceiver
,以宣告應用程式提供的限制。系統會叫用這項意圖來查詢
再建構 UI,讓主要使用者能夠
管理每個受限設定檔的限制
在以下項目的 onReceive()
方法中:
您的 BroadcastReceiver
,必須為每個應用程式提供的限制建立 RestrictionEntry
。每個 RestrictionEntry
都會定義限制標題、說明,以及
下列資料類型:
TYPE_BOOLEAN
,限制在此條件下為 可以是 true 或 false。TYPE_CHOICE
,限制使用 互斥的選項 (圓形按鈕選項)。TYPE_MULTI_SELECT
,設下限制 提供多種選項,且「並非」互斥 (核取方塊選項)。
接著,將所有 RestrictionEntry
物件放入 ArrayList
,並放入廣播接收器的結果做為
外加 EXTRA_RESTRICTIONS_LIST
。
系統會在「設定」應用程式中為應用程式限制建立 UI 並儲存
限制根據您為每個 RestrictionEntry
提供的專屬金鑰
物件。使用者開啟應用程式時,您可以透過下列方式查詢目前限制:
正在撥打 getApplicationRestrictions()
。
這會傳回 Bundle
,其中包含每個限制的鍵/值組合
您用 RestrictionEntry
物件來定義
如要提供布林值無法處理的特定限制,
以及複選值,然後您可以建立活動,讓使用者可以指定
,允許使用者透過限制設定開啟活動。在您的
廣播接收器,請加入額外的 EXTRA_RESTRICTIONS_INTENT
在結果 Bundle
中。此額外項目必須指定 Intent
用於指出要啟動的 Activity
類別 (使用
putParcelable()
方法,以便透過意圖傳遞 EXTRA_RESTRICTIONS_INTENT
)。
當主要使用者進入活動並設定自訂限制時,
接著,活動就必須使用
EXTRA_RESTRICTIONS_LIST
或 EXTRA_RESTRICTIONS_BUNDLE
鍵 (取決於您指定的方式)
RestrictionEntry
物件或鍵/值組合。
支援受限設定檔的帳戶
加入主要使用者的所有帳戶都能存取設有限制的設定檔
根據預設,使用者無法透過 AccountManager
API 存取帳戶。
如果您嘗試在受限的狀態下新增「AccountManager
」帳戶
就會顯示失敗結果基於這些限制,您有以下的容器:
三個選項:
如要透過受限設定檔存取帳戶,您必須在 <application> 標記中加入 android:restrictedAccountType
屬性:
<application ... android:restrictedAccountType="com.example.account.type" >
注意:啟用這個屬性可讓您 應用程式可透過設有限制的個人資料存取主要使用者的帳戶。所以您應該 只有在應用程式顯示的資訊不會透露個人識別資訊時 可視為敏感的資訊 (PII)。系統設定會將 您的應用程式會將設有限制的個人資料授予使用者帳戶,因此必須讓使用者清楚瞭解 帳戶存取權對於應用程式功能至關重要。可能的話,也建議您 為主要使用者提供適當的限制控制項,讓他們定義帳戶存取權多寡 允許在您的應用程式內。
如要使用帳戶,但應用程式的主要並未要求使用帳戶
你可以查看帳戶可用性,以及停用無法使用的功能。
請先檢查目前是否有可用帳戶。如果不是,則查詢
你可以呼叫 getUserRestrictions()
來建立新帳戶,並查看結果中的 DISALLOW_MODIFY_ACCOUNTS
額外項目。如果是 true
,
您應停用應用程式中任何需要存取帳戶的功能。
例如:
Kotlin
val um = context.getSystemService(Context.USER_SERVICE) as UserManager val restrictions: Bundle = um.userRestrictions if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) { // cannot add accounts, disable some functionality }
Java
UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); Bundle restrictions = um.getUserRestrictions(); if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) { // cannot add accounts, disable some functionality }
注意:在這種情況下,請勿宣告 任何新屬性。
相反地,如果應用程式設有限制,不能開放設有限制的個人資料
應用程式仰賴帳戶中的敏感個人資訊 (也因為設有限制的個人資料)
目前無法新增帳戶),請新增
將 android:requiredAccountType
屬性新增至 <application> 標記:
<application ... android:requiredAccountType="com.example.account.type" >
舉例來說,Gmail 應用程式會使用這項屬性來停用設有限制的個人資料。 因為擁有者的自己的個人電子郵件地址不適用於設有限制的個人資料。
無線與連線
藍牙低功耗 (採用智慧技術)
Android 現在支援透過 android.bluetooth
中的新 API 支援藍牙低功耗 (LE)。
有了新的 API,您就能建構可透過藍牙低功耗通訊的 Android 應用程式
心率監測器和計步器等周邊裝置。
因為藍牙 LE 是硬體功能
如果是 Android 裝置,您必須在資訊清單檔案中宣告 <uses-feature>
"android.hardware.bluetooth_le"
的元素:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
如果您已熟悉 Android 的傳統藍牙 API,請留意
藍牙 LE API 有些許差異。最重要的是,現在有 BluetoothManager
類別應用於部分高階作業
例如取得 BluetoothAdapter
、取得
以及檢查裝置狀態舉例來說,現在您應該
BluetoothAdapter
:
Kotlin
val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager bluetoothAdapter = bluetoothManager.adapter
Java
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter();
如要尋找藍牙 LE 週邊裝置,請在 BluetoothAdapter
上呼叫 startLeScan()
並傳遞實作項目
(位於 BluetoothAdapter.LeScanCallback
介面) 中。藍牙連線時
轉接器偵測到藍牙 LE 週邊裝置,您的 BluetoothAdapter.LeScanCallback
實作方式會收到對
onLeScan()
方法。這個
方法會提供 BluetoothDevice
物件,代表
裝置的 RSSI 值,以及包含裝置的
廣告記錄。
如果只想掃描特定類型的周邊裝置,可以改為呼叫 startLeScan()
,並加入 UUID
物件陣列,指定應用程式支援的 GATT 服務。
注意:掃描只能掃描藍牙 LE 裝置。 使用舊版 API 掃描傳統藍牙裝置。無法同時掃描 LE 和 Classic 同時支援藍牙裝置
接著,如要連線到藍牙 LE 週邊裝置,請在對應的用戶端上呼叫 connectGatt()
BluetoothDevice
物件,然後向該物件傳遞
BluetoothGattCallback
。BluetoothGattCallback
實作項目會接收連線相關回呼
狀態資訊,onConnectionStateChange()
期間
如果方法將 STATE_CONNECTED
做為新狀態傳遞,則您可以開始與裝置通訊。
如要存取裝置上的藍牙功能,應用程式還必須要求確保 藍牙使用者權限。詳情請參閱 Bluetooth Low Energy API 指南。
僅掃描 Wi-Fi 模式
Android 嘗試辨識使用者的位置時,可能會使用 Wi-Fi 協助判斷 掃描附近存取點來指出位置不過,使用者通常會關閉 Wi-Fi, 可節省電池電力,導致位置資料較不準確。Android 現在包含 開啟純掃描模式,裝置可連上 Wi-Fi 來掃描存取點,以便取得位置資訊 因此會大幅減少電池用量。
如果您想取得使用者的位置資訊,但 Wi-Fi 目前已關閉,可以要求
使用者要啟用僅限 Wi-Fi 掃描模式,方法是使用 ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE
動作呼叫 startActivity()
。
Wi-Fi 設定
全新的 WifiEnterpriseConfig
API 可讓企業導向服務
自動為受管理的裝置設定 Wi-Fi。
接聽來電時應答短訊
自 Android 4.0 起,名為「快速回應」的功能讓使用者能在
透過手機即時傳送簡訊,無需接聽電話或解鎖裝置。
在此之前,這些快速訊息一律是由預設的「訊息」應用程式處理。現在所有應用程式
您可以建立 Service
,宣告自身處理這些訊息的功能
建立 ACTION_RESPOND_VIA_MESSAGE
意圖篩選器
當使用者以快速回應回覆來電時,「電話」應用程式會傳送
包含 URI 的 ACTION_RESPOND_VIA_MESSAGE
意圖
說明接收者 (來電者) 和 EXTRA_TEXT
的額外項目
以及要傳送的訊息。服務收到意圖後,應提供
並立即停止 (應用程式不應顯示活動)。
您必須宣告 SEND_RESPOND_VIA_MESSAGE
權限,才能接收此意圖。
多媒體
MediaExtractor 和 MediaCodec 強化功能
Android 現在可讓您輕鬆編寫自己的動態自動調整功能
根據 ISO/IEC 23009-1 標準,透過 HTTP (DASH) 播放器串流
使用 MediaCodec
和 MediaExtractor
中現有的 API。這些 API 的基礎架構已更新,以便支援
剖析片段的 MP4 檔案時,您的應用程式仍負責剖析 MPD 中繼資料
並將個別串流傳遞至 MediaExtractor
。
如果您要將 DASH 與加密內容搭配使用,請注意 getSampleCryptoInfo()
方法會傳回說明每個加密媒體結構的 MediaCodec.CryptoInfo
中繼資料
樣本。此外,getPsshInfo()
方法已新增至
MediaExtractor
:可讓您存取 DASH 媒體的 PSSH 中繼資料。
這個方法會將 UUID
物件對應傳回位元組,
用於指定加密配置的 UUID
,以及代表資料專屬的位元組
並套用到該配置
媒體 DRM
新的 MediaDrm
類別提供數位版權的模組化解決方案
將 DRM 問題和媒體播放的區別開來,運用您的媒體內容管理 (DRM)。適用對象
例如,這種 API 分隔方式可讓您在不想要
使用 Widevine 媒體格式這個 DRM 解決方案也支援 DASH 通用加密,
可以在你的串流內容中使用各種數位版權管理配置。
您可使用 MediaDrm
取得不透明的按鍵要求訊息和處理程序
伺服器發出的金鑰回應訊息,用於取得授權及佈建授權。您的應用程式類型為
負責處理與伺服器之間的網路通訊;MediaDrm
類別只提供產生及處理訊息的功能。
MediaDrm
API 應與
Android 4.1 (API 級別 16) 中引入的 MediaCodec
API,
包括用於編碼及解碼內容的 MediaCodec
、用於處理加密內容的 MediaCrypto
和 MediaExtractor
以便擷取及複製內容
您必須先建構 MediaExtractor
和
MediaCodec
物件。接著,您就可以使用 DRM 識別碼識別機制
UUID
,通常來自內容的中繼資料,並用來建構
MediaDrm
物件的例項及其建構函式。
來自 Surface 的影片編碼
Android 4.1 (API 級別 16) 新增了低階的 MediaCodec
類別
媒體內容的編碼與解碼作業以 Android 4.1 編碼影片時,您必須提供
使用 ByteBuffer
陣列的媒體,但 Android 4.3 現在支援使用 Surface
做為編碼器的輸入內容。例如,將輸入編碼
或者使用從 OpenGL ES 產生的影格)。
如要使用 Surface
做為編碼器的輸入來源,請先為 MediaCodec
呼叫 configure()
。
然後呼叫 createInputSurface()
來接收用於串流媒體的 Surface
。
舉例來說,您可以使用指定的 Surface
做為 OpenGL 視窗
並傳遞至 eglCreateWindowSurface()
接著,在算繪介面時呼叫 eglSwapBuffers()
,將影格傳遞至 MediaCodec
。
如要開始編碼,請在 MediaCodec
上呼叫 start()
。完成後,請呼叫 signalEndOfInputStream()
終止編碼,並呼叫 release()
上的
Surface
。
媒體混合
新的 MediaMuxer
類別可在一個音訊串流之間啟用多工處理
和一個影片串流這些 API 做為 MediaExtractor
的對應項目
在 Android 4.2 中新增的類別,用於 de-Multixing (demuxing) 媒體。
MediaMuxer.OutputFormat
已定義支援的輸出格式。目前,
MP4 是唯一支援的輸出格式,而 MediaMuxer
目前支援這種格式。
一次只能使用一個音訊串流和/或一個影片串流。
MediaMuxer
主要用於與 MediaCodec
搭配使用
方便您透過 MediaCodec
處理影片,然後儲存
透過 MediaMuxer
輸出至 MP4 檔案也可以搭配使用 MediaMuxer
和 MediaExtractor
以提升成效
就能直接在媒體編輯中編輯,不需要編碼或解碼。
RemoteControlClient 的播放進度和拖曳
在 Android 4.0 (API 級別 14) 中,RemoteControlClient
已新增至
啟用遠端控制用戶端提供的媒體播放控制項,例如
鎖定螢幕。Android 4.3 現在提供這類控制器顯示播放的功能
位置和控制項。如果您已為
使用 RemoteControlClient
API 播放媒體應用程式,您就可以允許播放
實作兩個新介面。
首先,將 FLAG_KEY_MEDIA_POSITION_UPDATE
標記傳遞至
setTransportControlsFlags()
。
然後實作以下兩個新介面:
RemoteControlClient.OnGetPlaybackPositionListener
- 這包含要求目前位置的回呼
onGetPlaybackPosition()
媒體控制項。 RemoteControlClient.OnPlaybackPositionUpdateListener
- 這包含回呼
onPlaybackPositionUpdate()
, 當使用者使用 遠端控制 UI以新位置更新播放內容後,請呼叫
setPlaybackState()
來表示 新的播放狀態、位置和速度
定義這些介面後,您可以呼叫 setOnGetPlaybackPositionListener()
並RemoteControlClient
setPlaybackPositionUpdateListener()
。
圖形
支援 OpenGL ES 3.0
Android 4.3 版為 OpenGL ES 3.0 新增了 Java 介面和原生支援。主要新功能 OpenGL ES 3.0 包含:
- 進階視覺效果
- 以高品質的 ETC2/EAC 紋理壓縮為標準功能
- 新版 GLSL ES 陰影語言,支援整數和 32 位元浮點
- 進階紋理轉譯
- 擴大紋理大小和轉譯緩衝區格式的標準化
GLES30
提供適用於 Android 的 OpenGL ES 3.0 的 Java 介面。
使用 OpenGL ES 3.0 時,請務必使用
<uses-feature>
標記和 android:glEsVersion
屬性。例如:
<manifest> <uses-feature android:glEsVersion="0x00030000" /> ... </manifest>
請記得呼叫 setEGLContextClientVersion()
來指定 OpenGL ES 情境。
傳遞 3
做為版本
進一步瞭解如何使用 OpenGL ES,包括如何檢查裝置是否支援 OpenGL ES 版本在執行階段,請參閱 OpenGL ES API 指南。
可繪項目的 mipmap
以 mipmap 做為點陣圖或可繪項目的來源可讓您輕鬆 和多種圖片大小的比例,如果您覺得 要在動畫播放期間縮放的圖片
Android 4.2 (API 級別 17) 已在 Bitmap
中新增對 mipmap 的支援
類別—當您移動到 Bitmap
中的 mip 圖片時,
提供 mipmap 來源並啟用 setHasMipMap()
。現在,在 Android 4.3 中,您也可以提供 mipmap 資產,為 BitmapDrawable
物件啟用 mipmap :
在點陣圖資源檔案中設定 android:mipMap
屬性,或呼叫 hasMipMap()
。
使用者介面
查看疊加層
新的 ViewOverlay
類別會在頂端提供透明圖層
可用來新增視覺內容且不會影響的 View
版面配置階層您可以呼叫 getOverlay()
來取得任何 View
的 ViewOverlay
。疊加畫面
其大小和位置一律與主機檢視畫面 (建立該檢視畫面的檢視畫面) 相同,
可讓你新增顯示在主機檢視畫面前方的內容,但無法延伸
該主機檢視的邊界。
如果您要建立 ViewOverlay
動畫,例如將檢視畫面滑動至容器外,或是在畫面上移動項目
而不影響檢視區塊階層不過,由於疊加層的可用區域是
僅限與主機檢視畫面相同的區域;如要動畫呈現檢視畫面在外移動
您必須在版面配置中使用疊加層,而該上層檢視必須具有所需
版面配置的邊界
為小工具檢視畫面 (例如 Button
) 建立疊加層時,
可藉由呼叫Drawable
add(Drawable)
。如果您針對版面配置檢視畫面呼叫 getOverlay()
(例如 RelativeLayout
),
傳回的物件為 ViewGroupOverlay
。
ViewGroupOverlay
類別是子類別
的 ViewOverlay
,這也可讓您新增 View
呼叫 add(View)
來建立物件
注意:所有新增至疊加層的可繪項目和檢視畫面 都只有影像內容無法接收焦點或輸入事件。
舉例來說,以下程式碼會動畫呈現向右滑步檢視畫面的動畫: ,然後對該檢視區塊執行翻譯動畫:
Kotlin
val view: View? = findViewById(R.id.view_to_remove) val container: ViewGroup? = view?.parent as ViewGroup container?.apply { overlay.add(view) ObjectAnimator.ofFloat(view, "translationX", right.toFloat()) .start() }
Java
View view = findViewById(R.id.view_to_remove); ViewGroup container = (ViewGroup) view.getParent(); container.getOverlay().add(view); ObjectAnimator anim = ObjectAnimator.ofFloat(view, "translationX", container.getRight()); anim.start();
光學邊界版面配置
針對包含 nine-patch 背景圖片的檢視畫面,您現在可以指定其 與鄰近的視圖對齊例如背景圖片的邊界 大於「clip」檢視畫面的邊界。
例如,圖 1 和圖 2 各自顯示相同的版面配置,但圖 1 中的版本是 使用裁切範圍 (預設行為),而圖 2 使用光學邊界。由於 用於按鈕和相框的 nine-patch 圖片和邊緣周圍的邊框間距, 使用剪裁邊界時,這些邊界看起來不會對齊或文字。
注意:圖 1 和圖 2 中的螢幕截圖有「顯示」 layout 界限」開發人員設定已啟用。以紅線表示各視圖的光學 邊界,藍色線條表示裁剪範圍,粉紅色則代表邊界。
![](https://developer.android.google.cn/static/images/tools/clipbounds_2x.png?authuser=19&hl=zh-tw)
圖 1. 使用裁剪邊界的版面配置 (預設)。
![](https://developer.android.google.cn/static/images/tools/opticalbounds_2x.png?authuser=19&hl=zh-tw)
圖 2. 使用光學邊界的版面配置。
如要根據光學邊界對齊檢視區塊,請在其中一個父項版面配置中將 android:layoutMode
屬性設為 "opticalBounds"
。例如:
<LinearLayout android:layoutMode="opticalBounds" ... >
![](https://developer.android.google.cn/static/images/tools/ninepatch_opticalbounds_2x.png?authuser=19&hl=zh-tw)
圖 3. Holo 按鈕 nine-patch 的縮放檢視畫面 光學邊界。
為此,套用至檢視區塊背景的 nine-patch 圖片必須指定 在 nine-patch 檔案的底部和右側以紅線繪製光學邊界 (如 如圖 3 所示)。紅線表示應扣掉哪些區域 剪裁邊界,保留圖片的光學邊界。
在版面配置中啟用 ViewGroup
的光學邊界時,
子系檢視畫面會沿用光學邊界的版面配置模式,除非您針對分組依據覆寫該模式
將android:layoutMode
設為"clipBounds"
。所有版面配置元素也都會遵循
孩子視圖的光學邊界,自行根據其光學邊界來調整邊界
以及當中的檢視畫面但版面配置元素 (ViewGroup
的子類別)
目前並不支援套用到自己背景的 nine-patch 圖片的光學邊界。
如果您透過將 View
、ViewGroup
或任何子類別的子類別建立自訂檢視區塊,檢視區塊將繼承這些光學邊界行為。
注意:Holo 主題支援的所有小工具皆已更新
以及光學邊界,包括 Button
、Spinner
EditText
等。設定 GCP 資源後
如果您的應用程式套用 Holo 主題,則 android:layoutMode
屬性為 "opticalBounds"
(Theme.Holo
、Theme.Holo.Light
等)。
如要使用「Draw 9-patch」工具為自己的 nine-patch 圖片指定光學邊界,請在執行以下動作時按住 Control 鍵 不需要按一下邊框像素
矩形值的動畫
您現在可以使用新的 RectEvaluator
,在兩個 Rect
值之間建立動畫。這個新類別是 TypeEvaluator
的實作,您可以傳遞至 ValueAnimator.setEvaluator()
。
視窗附加和焦點事件監聽器
過去,如果您想監聽檢視畫面附加/卸離視窗的時間,或者
當焦點變更時,您需要覆寫 View
類別,才能
請分別實作 onAttachedToWindow()
和 onDetachedFromWindow()
,或 onWindowFocusChanged()
。
現在,如要接收附加及卸離事件,可以改為實作 ViewTreeObserver.OnWindowAttachListener
,然後在具有
addOnWindowAttachListener()
。
如要接收聚焦事件,可以實作 ViewTreeObserver.OnWindowFocusChangeListener
,並利用
addOnWindowFocusChangeListener()
。
電視過度掃描支援
為確保應用程式會在每台電視上填滿整個畫面,你可以啟用過度掃描功能
自訂顯示功能過度掃描模式取決於 FLAG_LAYOUT_IN_OVERSCAN
旗標,您可以透過下列平台主題啟用該模式,例如:
Theme_DeviceDefault_NoActionBar_Overscan
或啟用
自訂主題中的 windowOverscan
樣式。
螢幕方向
<activity>
標記的 screenOrientation
屬性現在支援其他值,以遵循使用者的自動旋轉偏好設定:
"userLandscape"
- 運作方式與
"sensorLandscape"
相同,除非使用者停用自動旋轉功能 則會鎖定一般的橫向模式,不會翻轉 "userPortrait"
- 運作方式與
"sensorPortrait"
相同,除非使用者停用自動旋轉功能, 會鎖定為一般直向,而不會翻轉。 "fullUser"
- 運作方式與
"fullSensor"
相同,且允許朝全部四個方向旋轉,除了 如果使用者停用自動旋轉功能,系統會鎖定使用者偏好的方向。
此外,現在您也可以宣告 "locked"
,將應用程式的螢幕方向鎖定為
螢幕目前的螢幕方向
旋轉動畫
新的 rotationAnimation
欄位位於
WindowManager
提供三種動畫任您挑選
希望在系統切換螢幕方向時使用。這三種動畫如下:
注意:你必須將活動設為使用「全螢幕」,才能使用這些動畫模式,此模式可透過 Theme.Holo.NoActionBar.Fullscreen
等主題啟用。
下例說明如何啟用「交叉漸變」動畫:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val params: WindowManager.LayoutParams = window.attributes params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE window.attributes = params ... }
Java
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); WindowManager.LayoutParams params = getWindow().getAttributes(); params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE; getWindow().setAttributes(params); ... }
使用者輸入內容
全新感應器類型
全新的 TYPE_GAME_ROTATION_VECTOR
感應器可以偵測裝置的旋轉情形,不必擔心受到磁性幹擾。與 TYPE_ROTATION_VECTOR
感應器不同,TYPE_GAME_ROTATION_VECTOR
並非以磁北做為依據。
新的 TYPE_GYROSCOPE_UNCALIBRATED
和 TYPE_MAGNETIC_FIELD_UNCALIBRATED
感應器會提供原始感應器資料,但不含
會將偏誤估算納入考量也就是說,現有的 TYPE_GYROSCOPE
和 TYPE_MAGNETIC_FIELD
感應器提供的感應器資料會將陀螺儀和硬鐵的預估偏誤納入考量
分別位於裝置中而新的「未校正」改為提供這些感應器的版本
原始感應器資料,並分別提供預估偏誤值。這些感應器可讓你
使用以下項目提升預估偏誤,為感應器資料提供專屬校正
外部資料。
通知監聽器
Android 4.3 新增了 NotificationListenerService
服務類別,可讓應用程式在系統發布新通知時,立即接收相關資訊。
如果您的應用程式目前是使用無障礙服務 API 存取系統通知,則應更新應用程式,改為使用這些 API。
聯絡人供應程式
查詢「可聯絡項目」
透過 Contactables.CONTENT_URI
最新的聯絡人提供者查詢,您可以輕鬆取得一個 Cursor
,其中包含所有符合指定查詢的聯絡人的電子郵件地址和電話號碼。
查詢聯絡人 Deltas
我們在聯絡人供應商中加入新的 API,可讓您有效率地查詢聯絡人資料近期的變更。過去,當聯絡人資料有所變更時,您的應用程式會收到通知,但您還不知道異動內容,因此需要擷取所有聯絡人,才能反覆查看來發現異動內容。
如要追蹤插入和更新作業的變更項目,您現在可以在選取項目中加入 CONTACT_LAST_UPDATED_TIMESTAMP
參數,只查詢上次查詢供應商後已變更的聯絡人。
新的表格「ContactsContract.DeletedContacts
」會提供已刪除的聯絡人記錄,藉此追蹤已刪除的聯絡人 (每個刪除的聯絡人都會保留在這個表格中一段時間)。與 CONTACT_LAST_UPDATED_TIMESTAMP
類似,您可以使用新的選取參數 CONTACT_DELETED_TIMESTAMP
查看自您上次查詢供應商以來,哪些聯絡人已遭刪除。該資料表也會包含常數 DAYS_KEPT_MILLISECONDS
,其中包含記錄保留的天數 (以毫秒為單位)。
此外,聯絡人供應程式現在會在使用者觀看時廣播 CONTACTS_DATABASE_CREATED
動作
透過系統設定選單清除聯絡人儲存空間,有效重新建立
聯絡人提供者資料庫。這項功能是用來告知應用程式必須放下所有聯絡人
使用者儲存的資訊,然後使用新的查詢重新載入資料。
如需使用這些 API 的程式碼範例檢查聯絡人異動,請查看 ApiDemos SDK 範例下載所提供的範例。
本地化
改善雙向文字支援功能
舊版 Android 支援從右到左 (RTL) 的語言和版面配置,
但有時無法正確處理混合方向文字因此,Android 4.3 新增了 BidiFormatter
API,可協助您以反方向正確設定文字格式
而且內容本身不會太過雜亂
例如,您想使用字串變數建立句子,例如「您是不是要查」
15 Bay Street, Laurel, CA?",你通常會將經過本地化的字串資源與變數傳送至
String.format()
:
Kotlin
val suggestion = String.format(resources.getString(R.string.did_you_mean), address)
Java
Resources res = getResources(); String suggestion = String.format(res.getString(R.string.did_you_mean), address);
不過,如果語言代碼是希伯來文,則格式化字串會顯示為:
האם התכוונת ל 15 Bay Street, Laurel, CA?
答錯了,「15」應該在「海灣街」留下。解決方法是使用 BidiFormatter
和其 unicodeWrap()
方法。舉例來說,上述程式碼會變成:
Kotlin
val bidiFormatter = BidiFormatter.getInstance() val suggestion = String.format( resources.getString(R.string.did_you_mean), bidiFormatter.unicodeWrap(address) )
Java
Resources res = getResources(); BidiFormatter bidiFormatter = BidiFormatter.getInstance(); String suggestion = String.format(res.getString(R.string.did_you_mean), bidiFormatter.unicodeWrap(address));
根據預設,unicodeWrap()
會使用
第一個強而有力的方向評估經驗法則,如果一
文字方向的訊號並不代表內容整體的適當方向。
如有必要,您可以從 TextDirectionHeuristics
傳遞其中一個 TextDirectionHeuristic
常數,以指定其他經驗法則
至 unicodeWrap()
。
注意:這些新的 API 也適用於先前版本
進入 Android 支援
程式庫,提供 BidiFormatter
類別和相關 API。
無障礙服務
處理重要事件
AccessibilityService
現在可以接收以下項目的回呼:
使用 onKeyEvent()
回呼方法的按鍵輸入事件。這樣一來,無障礙服務就能處理以下項目的輸入內容:
鍵盤和鍵盤等以按鍵為基礎的輸入裝置,並將這些事件轉譯為特殊動作,
這可能只靠觸控輸入或裝置方向鍵操作。
選取文字並複製/貼上
AccessibilityNodeInfo
現在提供 API
用於選取、剪下、複製及貼上的 AccessibilityService
也就是節點中的文字
你的無障礙服務可以使用新的
動作、ACTION_SET_SELECTION
,通過
其起點和終點為 ACTION_ARGUMENT_SELECTION_START_INT
和 ACTION_ARGUMENT_SELECTION_END_INT
。
您也可以使用現有的現有文件,操控遊標位置來選取文字
動作、ACTION_NEXT_AT_MOVEMENT_GRANULARITY
(先前僅適用於移動遊標位置),以及新增引數 ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
。
接著,你可以使用 ACTION_CUT
剪下或複製檔案,
ACTION_COPY
,之後貼上
ACTION_PASTE
。
注意:這些新的 API 也適用於先前版本
進入 Android 支援
程式庫,其中採用 AccessibilityNodeInfoCompat
類別
宣告無障礙功能
從 Android 4.3 開始,無障礙服務必須宣告無障礙功能
中繼資料檔案,即可使用特定無障礙功能。如果功能不在
已要求提供資訊,這項功能只是免人工管理。如要宣告服務的
無障礙功能,請務必使用與
「功能」AccessibilityServiceInfo
中的常數
類別
例如,如果服務未要求 flagRequestFilterKeyEvents
功能,
就無法接收重要事件
測試和偵錯
自動化 UI 測試
新的 UiAutomation
類別提供可用來模擬使用者的 API
測試自動化動作。使用平台的 AccessibilityService
API,UiAutomation
API 可讓您檢查畫面內容,並插入任意鍵盤和觸控事件。
如要取得 UiAutomation
的例項,請呼叫 Instrumentation.getUiAutomation()
。在訂單中
為此,您必須透過 instrument
指令提供 -w
選項。
透過 adb shell
執行 InstrumentationTestCase
時。
您可以透過 UiAutomation
例項執行任意事件來測試
呼叫 executeAndWaitForEvent()
,並傳遞要執行的 Runnable
、逾時
作業持續時間,以及 UiAutomation.AccessibilityEventFilter
介面的實作。它位於 UiAutomation.AccessibilityEventFilter
實作中,您會接到呼叫
篩選感興趣的事件
藉此判斷成效
以及指定的測試案例失敗
如要在測試期間觀察所有事件,請建立 UiAutomation.OnAccessibilityEventListener
的實作並傳遞至 setOnAccessibilityEventListener()
。
接著,事件監聽器介面會收到對 onAccessibilityEvent()
的呼叫
每次事件發生時接收 AccessibilityEvent
物件
描述該事件
UiAutomation
API 提供許多其他各種作業
,以便鼓勵開發 uiautomator 等 UI 測試工具。舉例來說:
UiAutomation
也可以:
- 插入輸入事件
- 變更螢幕方向
- 擷取螢幕截圖
最重要的是,UiAutomation
API 對 UI 測試工具要發揮作用
跨應用程式界線,與 Instrumentation
中的值不同。
應用程式的 Systrace 事件
Android 4.3 新增了包含兩個靜態方法的 Trace
類別。
beginSection()
和endSection()
,
定義要納入 Systrace 報表的程式碼區塊。建立
應用程式追蹤的程式碼區段,Systrace 記錄檔可提供更詳細的資訊
透過分析瞭解應用程式中速度變慢的區塊
如要進一步瞭解如何使用 Systrace 工具,請參閱「使用 Systrace 分析顯示內容和效能」。
安全性
應用程式私密金鑰的 Android 金鑰儲存庫
Android 現在在 KeyStore
中提供自訂的 Java 安全性提供者
Android Key Store 可讓您產生並儲存
只有您的應用程式看得到及使用。如要載入 Android Key Store,請
"AndroidKeyStore"
到 KeyStore.getInstance()
。
如要在 Android Key Store 中管理應用程式的私人憑證,請使用以下指令產生新金鑰:
KeyPairGeneratorSpec
會員價 KeyPairGenerator
。頭等艙
呼叫 getInstance()
以取得 KeyPairGenerator
的例項。然後呼叫
initialize()
,並向其傳送
KeyPairGeneratorSpec
,您可以使用
KeyPairGeneratorSpec.Builder
。
最後,呼叫 generateKeyPair()
以取得 KeyPair
。
硬體憑證儲存空間
Android 現在也支援硬體備份的 KeyChain
儲存空間
憑證,藉此讓金鑰無法用於擷取,以提高安全性。也就是
金鑰位於硬體支援的金鑰儲存庫 (安全元件、TPM 或 TrustZone) 中,即可用於
,但無法匯出私密金鑰內容。甚至是 OS 核心
無法存取這個金鑰內容。雖然並非所有 Android 裝置都支援
硬體,您可以在執行階段中呼叫
KeyChain.IsBoundKeyAlgorithm()
。
資訊清單宣告
可宣告的必要功能
<uses-feature>
現在支援下列值
元素,確保應用程式只安裝在提供功能的裝置上
應用程式的需求
FEATURE_APP_WIDGETS
- 宣告應用程式提供應用程式小工具,且只能安裝在符合下列條件的裝置上
在網站上嵌入應用程式小工具,或是顯示類似位置。
範例如下:
<uses-feature android:name="android.software.app_widgets" android:required="true" />
FEATURE_HOME_SCREEN
- 宣告應用程式的行為為取代主畫面,且只應安裝在
裝置 (支援第三方主畫面應用程式)。
範例如下:
<uses-feature android:name="android.software.home_screen" android:required="true" />
FEATURE_INPUT_METHODS
- 宣告應用程式提供自訂輸入法 (使用
InputMethodService
建構的鍵盤),且應只安裝在下列裝置上: 支援第三方輸入法 範例如下:<uses-feature android:name="android.software.input_methods" android:required="true" />
FEATURE_BLUETOOTH_LE
- 宣告應用程式使用 Bluetooth Low Energy API,且應只安裝在裝置上
支援藍牙低功耗技術與其他裝置通訊
範例如下:
<uses-feature android:name="android.software.bluetooth_le" android:required="true" />
使用者權限
<uses-permission>
現在支援下列值
宣告
權限。
BIND_NOTIFICATION_LISTENER_SERVICE
- 必須使用新的
NotificationListenerService
API。 SEND_RESPOND_VIA_MESSAGE
- 取得
ACTION_RESPOND_VIA_MESSAGE
所需的必要欄位 意圖。
如需 Android 4.3 中所有 API 變更的詳細檢視畫面,請參閱 API 差異報告。