應用程式小工具是小型的應用程式檢視畫面,可嵌入其他 應用程式 (例如主畫面),並接收定期更新。這些 在使用者介面中稱為「小工具」,您可以發布 搭配應用程式小工具供應商 (或小工具供應商) 的一種。一種應用程式元件 保存其他小工具稱為應用程式小工具主機 (或小工具主機)。圖 1 會顯示一個音樂小工具範例:
本文件說明如何使用小工具供應器發布小工具。適用對象
自行建立 AppWidgetHost
的詳細資訊
代管應用程式小工具,請參閱「建構小工具主機」。
如要瞭解如何設計小工具,請參閱「應用程式小工具總覽」。
小工具元件
如要建立小工具,您需要下列基本元件:
AppWidgetProviderInfo
物件- 說明小工具的中繼資料,例如小工具的版面配置、更新
頻率和
AppWidgetProvider
類別AppWidgetProviderInfo
是在 XML 中定義,如 AppWidgetProvider
類別- 定義基本方法,讓您可以透過程式輔助方式
有了這個應用程式,你就能在更新小工具時接收廣播訊息
已啟用、已停用或刪除您在
AppWidgetProvider
,然後實作這項功能, 。 - 查看版面配置
- 定義小工具的初始版面配置。版面配置定義於 如本文件所述,使用 XML 格式。
圖 2 顯示這些元件如何融入整體應用程式小工具處理作業 流程
,瞭解如何調查及移除這項存取權。如果需要使用者設定小工具,請實作應用程式小工具設定 活動。這個活動可讓使用者修改小工具設定,例如 時鐘小工具的時區
- 從 Android 12 (API 級別 31) 開始,您可以提供預設值 讓使用者稍後重新設定小工具。請參閱使用 小工具的預設設定和啟用 使用者可以重新設定放置的小工具 ,掌握更多詳細資訊。
- 在 Android 11 (API 級別 30) 以下版本中,每次都會啟動這個活動 將小工具新增至主畫面。
我們也建議採行以下改善項目:彈性小工具版面配置、其他強化功能、進階小工具、集合小工具,以及建構小工具 。
宣告 AppWidgetProviderInfo XML
AppWidgetProviderInfo
物件會定義小工具的基本特質。
使用一項,在 XML 資源檔案中定義 AppWidgetProviderInfo
物件
<appwidget-provider>
元素,並儲存至專案的 res/xml/
資料夾。
例如:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="40dp"
android:minHeight="40dp"
android:targetCellWidth="1"
android:targetCellHeight="1"
android:maxResizeWidth="250dp"
android:maxResizeHeight="120dp"
android:updatePeriodMillis="86400000"
android:description="@string/example_appwidget_description"
android:previewLayout="@layout/example_appwidget_preview"
android:initialLayout="@layout/example_loading_appwidget"
android:configure="com.example.android.ExampleAppWidgetConfigurationActivity"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen"
android:widgetFeatures="reconfigurable|configuration_optional">
</appwidget-provider>
小工具大小屬性
預設的主畫面根據儲存格格線,將小工具置於視窗中 設有明確的高度和寬度大多數主畫面都只允許小工具存取 大小為格線儲存格的整數倍數,例如兩個儲存格 垂直縮短三個儲存格
您可以利用小工具尺寸屬性,指定小工具的預設尺寸和 提供小工具大小的上下限。在此情況下, 小工具的預設大小是小工具首次啟動時採用的大小 。
下表說明相關的 <appwidget-provider>
屬性
調整小工具的大小
屬性與說明 | |
---|---|
「targetCellWidth 」和
targetCellHeight (Android 12)、
minWidth 和minHeight |
targetCellWidth 和
targetCellHeight 、minWidth 和
minHeight ,讓應用程式能改回使用
如果使用者的裝置為 minWidth 和 minHeight
不支援 targetCellWidth 和
targetCellHeight 。如果支援
targetCellWidth 和 targetCellHeight 屬性
的優先順序高於 minWidth 和 minHeight
屬性。
|
「minResizeWidth 」和
minResizeHeight |
指定小工具的絕對最小尺寸。這些值會指定
載入小工具後難以辨識或無法使用的尺寸。使用
這些屬性可讓使用者將小工具調整為更小的尺寸
大於預設的小工具大小minResizeWidth 屬性為
如果寬度大於 minWidth 或水平參數,就會遭到忽略
未啟用調整大小功能。詳情請見
resizeMode 。同樣地,
如果 minResizeHeight 屬性大於,則系統會忽略該屬性
minHeight ,或是未啟用垂直調整大小功能。 |
「maxResizeWidth 」和
maxResizeHeight |
指定小工具的建議大小上限。如果這些值並非
格狀儲存格尺寸的倍數,會四捨五入至最接近的
儲存格大小。如果 maxResizeWidth 屬性有,系統會忽略該屬性
小於 minWidth ,或是未水平調整其大小
請見 resizeMode 。同樣地
如果 maxResizeHeight 屬性較大,則系統會忽略這個屬性
大於 minHeight ,或是未啟用垂直調整大小功能。
相關元素已在 Android 12 中推出。 |
resizeMode |
指定小工具可調整大小的規則。您可以使用
屬性讓主畫面小工具可水平、垂直方向調整
或兩軸都顯示使用者觸碰並按住小工具即可顯示其大小調整控點
然後拖曳水平或垂直控點來變更
版面配置格線resizeMode 屬性的值包括:
horizontal 、vertical 和none 。目的地:
將小工具宣告為可水平和垂直調整大小,並使用
horizontal|vertical 。 |
範例
為了說明上表中的屬性對小工具大小有何影響, 假設下列規格如下:
- 格狀儲存格寬度為 30 dp,高度為 50 dp。
- 提供的屬性規格如下:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="80dp"
android:minHeight="80dp"
android:targetCellWidth="2"
android:targetCellHeight="2"
android:minResizeWidth="40dp"
android:minResizeHeight="40dp"
android:maxResizeWidth="120dp"
android:maxResizeHeight="120dp"
android:resizeMode="horizontal|vertical" />
自 Android 12 起:
使用 targetCellWidth
和 targetCellHeight
屬性做為預設值
這個小工具的大小
根據預設,小工具的大小為 2x2。您可以縮小至 2x1 或 最高可達 4x3。
Android 11 以下版本:
使用 minWidth
和 minHeight
屬性計算
預設寬度 = Math.ceil(80 / 30)
= 3
預設高度 = Math.ceil(80 / 50)
= 2
小工具的大小預設為 3x2。您可以縮小至 2x1 或 。
其他小工具屬性
下表說明相關的 <appwidget-provider>
屬性
不符合小工具尺寸以外的各種屬性
屬性與說明 | |
---|---|
updatePeriodMillis |
定義小工具架構要求從
呼叫 onUpdate() 即可 AppWidgetProvider
回呼方法。實際的更新不保證一定會在
做為此值的資料集更新頻率,建議您儘可能隨
,為了節省電池電力,每小時不超過一次。
如需選擇適當更新週期的完整注意事項清單,
看
小工具更新最佳化
內容。 |
initialLayout |
指向定義小工具版面配置的版面配置資源。 |
configure |
定義使用者新增小工具時啟動的活動。 讓使用者設定小工具屬性詳情請見 讓使用者自行設定小工具。 從 Android 12 開始,應用程式可以略過初始 此外還會從 0 自動調整資源配置 您完全不必調整資源調度設定請參閱使用 小工具的預設設定。 |
description |
指定小工具挑選器的顯示說明, 相關元素已在 Android 12 中推出。 |
previewLayout (Android 12)
和 previewImage (Android 11 以下版本) |
previewImage
和 previewLayout 屬性,讓應用程式能夠改回使用
在使用者的裝置不支援的情況下使用 previewImage
previewLayout 。詳情請參閱
與可擴充的回溯相容性
小工具預覽。
|
autoAdvanceViewId |
指定自動進階的小工具子檢視畫面檢視 ID 小工具的主機。 |
widgetCategory |
宣告小工具是否能顯示在主畫面上
(home_screen )、螢幕鎖定畫面 (keyguard ),或
兩者。如果是 Android 5.0 以上版本,只有 home_screen 有效。
|
widgetFeatures |
宣告小工具支援的功能。舉例來說
讓使用者的小工具套用預設設定、指定
configuration_optional 敬上
和
reconfigurable 。
旗標這樣就不必在使用者之後啟動設定活動
然後新增小工具使用者仍可
重新設定小工具
。 |
使用 AppWidgetProvider 類別處理小工具廣播訊息
AppWidgetProvider
類別會處理小工具廣播訊息並更新小工具
回應小工俱生命週期事件下列各節將說明如何
在資訊清單中宣告 AppWidgetProvider
,然後實作。
在資訊清單中宣告小工具
首先,請在應用程式的 AndroidManifest.xml
中宣告 AppWidgetProvider
類別
檔案,如以下範例所示:
<receiver android:name="ExampleAppWidgetProvider"
android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/example_appwidget_info" />
</receiver>
<receiver>
元素需要 android:name
屬性,也就是指定
小工具使用的 AppWidgetProvider
。不得匯出這個元件
除非有其他程序需要播送到 AppWidgetProvider
,
這些情況通常並非如此
<intent-filter>
元素必須包含 <action>
元素,
android:name
屬性。這項屬性會指定 AppWidgetProvider
接受
ACTION_APPWIDGET_UPDATE
廣播。這是唯一必須明確宣告的廣播訊息。
AppWidgetManager
敬上
會自動將所有其他小工具廣播訊息傳送到 AppWidgetProvider
,如
無從得知
<meta-data>
元素會指定 AppWidgetProviderInfo
資源和
須具備以下屬性:
android:name
:指定中繼資料名稱。使用android.appwidget.provider
,即可將資料視為AppWidgetProviderInfo
描述元。android:resource
:指定AppWidgetProviderInfo
資源 或 HTTP/HTTPS 位置
實作 AppWidgetProvider 類別
AppWidgetProvider
類別會擴充
BroadcastReceiver
,以
便利類別,可以處理小工具廣播訊息。只會收到事件
與小工具相關的廣播訊息,例如小工具更新時
已刪除、啟用和停用發生這類廣播事件時,會發生以下情況:
以下為呼叫 AppWidgetProvider
方法:
onUpdate()
- 系統會呼叫此方法,依照
AppWidgetProviderInfo
中的updatePeriodMillis
屬性。請參閱表格 在本頁說明其他小工具屬性 瞭解詳情 ,瞭解如何調查及移除這項存取權。
- 使用者新增小工具時,系統也會呼叫此方法,因此
例如為
View
物件或啟動要載入資料的工作 還可以顯示在小工具中不過,如果您宣告某個設定活動configuration_optional
標記,則當使用者 新增小工具,但後續更新會呼叫此小工具。第一種是 執行第一次更新作業的責任 設定完成詳情請參閱「允許使用者設定應用程式小工具」。 ,瞭解如何調查及移除這項存取權。
- 最重要的回呼是
onUpdate()
。請參閱「使用 詳情請參閱本頁中的onUpdate()
類別。 onAppWidgetOptionsChanged()
初次放置小工具時,只要小工具出現 已調整大小。使用這個回呼,根據小工具的大小顯示或隱藏內容 範圍。取得大小範圍,並從 Android 12 開始 小工具執行個體所能接收的大小清單 (方法是呼叫
getAppWidgetOptions()
、 會傳回一個Bundle
,其中包含 包括:OPTION_APPWIDGET_MIN_WIDTH
: 包含小工具執行個體的寬度下限 (以 dp 單位為單位)。OPTION_APPWIDGET_MIN_HEIGHT
: 包含小工具執行個體的高度下限 (以 dp 為單位)。OPTION_APPWIDGET_MAX_WIDTH
: 包含小工具執行個體的寬度上限 (以 dp 單位為單位)。OPTION_APPWIDGET_MAX_HEIGHT
: 包含小工具執行個體的高度上限 (以 dp 為單位)。OPTION_APPWIDGET_SIZES
: 包含可能的大小清單 (List<SizeF>
),以 dp 為單位, 可處理的小工具執行個體相關元素已在 Android 12 中推出。
onDeleted(Context, int[])
每次從小工具主機刪除小工具時,系統就會呼叫此方法。
onEnabled(Context)
當初次建立小工具的例項時,系統會呼叫此方法。 舉例來說,如果使用者在小工具中加入兩個例項,系統只會呼叫 首次完成的任務如果需要開啟新的資料庫或執行 所有小工具執行個體只需要執行一次,就很適合 親自體驗
onDisabled(Context)
從 您可以在這裡清除
onEnabled(Context)
中的所有工作 例如刪除暫存資料庫onReceive(Context, Intent)
針對每個廣播訊息、每個前一個回呼之前和之前,系統都會呼叫此方法 方法。您通常不需要實作此方法,因為
AppWidgetProvider
實作會篩選所有小工具廣播並呼叫 執行這些動作
您必須將 AppWidgetProvider
類別實作宣告為廣播訊息
使用 AndroidManifest
中的 <receiver>
元素接收端。請參閱宣告
小工具中的小工具,以取得更多資訊。
使用 onUpdate() 類別處理事件
最重要的 AppWidgetProvider
回呼是 onUpdate()
,因為這是
將每個小工具新增到主機時呼叫 ,除非您使用設定
沒有 configuration_optional
旗標的活動。如果您的小工具接受任何
然後在這個回呼中註冊事件處理常式。如果
小工具不會建立暫存檔案或資料庫,也不會執行其他作業
但 onUpdate()
是唯一需要清除的回呼方法
這些 Pod 需要定義
舉例來說,如果您想讓小工具具有啟動活動時的按鈕
輕觸後,您可以使用下列的 AppWidgetProvider
實作方式:
Kotlin
class ExampleAppWidgetProvider : AppWidgetProvider() { override fun onUpdate( context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray ) { // Perform this loop procedure for each widget that belongs to this // provider. appWidgetIds.forEach { appWidgetId -> // Create an Intent to launch ExampleActivity. val pendingIntent: PendingIntent = PendingIntent.getActivity( /* context = */ context, /* requestCode = */ 0, /* intent = */ Intent(context, ExampleActivity::class.java), /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) // Get the layout for the widget and attach an onClick listener to // the button. val views: RemoteViews = RemoteViews( context.packageName, R.layout.appwidget_provider_layout ).apply { setOnClickPendingIntent(R.id.button, pendingIntent) } // Tell the AppWidgetManager to perform an update on the current // widget. appWidgetManager.updateAppWidget(appWidgetId, views) } } }
Java
public class ExampleAppWidgetProvider extends AppWidgetProvider { public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // Perform this loop procedure for each widget that belongs to this // provider. for (int i=0; i < appWidgetIds.length; i++) { int appWidgetId = appWidgetIds[i]; // Create an Intent to launch ExampleActivity Intent intent = new Intent(context, ExampleActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity( /* context = */ context, /* requestCode = */ 0, /* intent = */ intent, /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE ); // Get the layout for the widget and attach an onClick listener to // the button. RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget_layout); views.setOnClickPendingIntent(R.id.button, pendingIntent); // Tell the AppWidgetManager to perform an update on the current app // widget. appWidgetManager.updateAppWidget(appWidgetId, views); } } }
此 AppWidgetProvider
只定義 onUpdate()
方法,使用此方法:
建立 PendingIntent
來啟動
Activity
,並附加至小工具的
按鈕 (使用 setOnClickPendingIntent(int,
PendingIntent)
)。其中包含可疊代每個項目的迴圈
appWidgetIds
中是一個 ID 陣列,用來識別由
使用這個供應商的服務如果使用者建立了多個小工具例項,則
都會同時更新不過,只有一個 updatePeriodMillis
排程
都會用於管理小工具的所有執行個體舉例來說,如果更新時間表
定義為每兩小時,接著新增一個小工具
並在第一個小時過後 1 小時,這兩種更新的時間都會按照
第一個更新期間,則會忽略第二個更新週期。他們每兩個端點都會更新一次
並非每小時
詳情請參閱
ExampleAppWidgetProvider.java
敬上
範例類別。
接收小工具廣播意圖
AppWidgetProvider
是便利類別。如果希望收到小工具
直接播送,您可以使用自己的 BroadcastReceiver
或覆寫
這個
onReceive(Context,Intent)
回呼。您需要關注的意圖
包括:
ACTION_APPWIDGET_UPDATE
ACTION_APPWIDGET_DELETED
ACTION_APPWIDGET_ENABLED
ACTION_APPWIDGET_DISABLED
ACTION_APPWIDGET_OPTIONS_CHANGED
建立小工具版面配置
您必須在 XML 中定義小工具的初始版面配置,並將其儲存至
專案的 res/layout/
目錄。詳情請參閱設計說明
指南。。
如果熟悉,建立小工具版面配置相當簡單
版面配置。不過請注意
以 RemoteViews
、
不支援每一種版面配置或檢視小工具您無法使用自訂欄位
RemoteViews
支援的檢視區塊或子類別。
RemoteViews
也支援 ViewStub
,
這是大小為零的隱藏 View
,可用來延後加載版面配置
執行特定工作
支援有狀態行為
Android 12 新增了支援有狀態行為的下列項目 現有元件
小工具仍為無狀態。您的應用程式必須儲存狀態並註冊 狀態變更事件。
,瞭解如何調查及移除這項存取權。以下程式碼範例說明如何實作這些元件。
Kotlin
// Check the view. remoteView.setCompoundButtonChecked(R.id.my_checkbox, true) // Check a radio group. remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2) // Listen for check changes. The intent has an extra with the key // EXTRA_CHECKED that specifies the current checked state of the view. remoteView.setOnCheckedChangeResponse( R.id.my_checkbox, RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent) )
Java
// Check the view. remoteView.setCompoundButtonChecked(R.id.my_checkbox, true); // Check a radio group. remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2); // Listen for check changes. The intent has an extra with the key // EXTRA_CHECKED that specifies the current checked state of the view. remoteView.setOnCheckedChangeResponse( R.id.my_checkbox, RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent));
提供兩種版面配置:一種指定搭載 Android 12 或
res/layout-v31
的升幅,而另一個
預設 res/layout
資料夾中包含 Android 11 以下版本。
實作圓角
Android 12 推出了下列系統參數,以便設定 小工具圓角的半徑:
system_app_widget_background_radius
: 小工具背景的圓角半徑,尺寸一律小於 28 dp。system_app_widget_inner_radius
: 小工具內任何檢視畫面的圓角半徑。等於 8 dp 小於背景半徑,以便在使用 8 dp 時清楚對齊 邊框間距。
下例中的小工具會使用
system_app_widget_background_radius
用於小工具角落,以及
針對小工具內的檢視畫面:system_app_widget_inner_radius
。
1 小工具的邊角。
2 小工具中檢視畫面的邊角。
圓角的重要注意事項
- 第三方啟動器和裝置製造商可以覆寫
system_app_widget_background_radius
參數必須小於 28 dp。system_app_widget_inner_radius
參數一律小於 8 dpsystem_app_widget_background_radius
的值。 - 如果小工具未使用
@android:id/background
或定義背景 影片大綱:android:clipToOutline
設為true
:啟動器會自動識別背景並 使用圓角不超過 16 dp 的矩形裁剪小工具。 請參閱確保您的小工具與 Android 12。
如要確保小工具與舊版 Android 的相容性,建議你 定義自訂屬性,並使用自訂主題來覆寫 Android 12,如下列 XML 範例檔案所示:
/values/attrs.xml
<resources>
<attr name="backgroundRadius" format="dimension" />
</resources>
/values/styles.xml
<resources>
<style name="MyWidgetTheme">
<item name="backgroundRadius">@dimen/my_background_radius_dimen</item>
</style>
</resources>
/values-31/styles.xml
<resources>
<style name="MyWidgetTheme" parent="@android:style/Theme.DeviceDefault.DayNight">
<item name="backgroundRadius">@android:dimen/system_app_widget_background_radius</item>
</style>
</resources>
/drawable/my_widget_background.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="?attr/backgroundRadius" />
...
</shape>
/layout/my_widget_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
android:background="@drawable/my_widget_background" />