在資訊方塊內顯示定期更新內容
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
建立可隨著時間變更內容的資訊方塊。
使用時間軸
時間軸含有一或多個 TimelineEntry
例項,每個例項各有一個會在特定時間間隔顯示的版面配置。所有資訊方塊都需要時間軸。

單一項目資訊方塊
資訊方塊通常可以用單一 TimelineEntry
說明。版面配置是固定的,只有版面配置中的資訊會變更。舉例來說,顯示當日健身進度的資訊方塊一律會顯示相同的進度版面配置,不過您可能會為了顯示不同的值而調整版面配置。在這種情況下,您無法事先得知內容何時會變更。
請參考以下設有單一 TimelineEntry
的資訊方塊範例:
override fun onTileRequest(
requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile?> {
val tile =
Tile.Builder()
.setResourcesVersion(RESOURCES_VERSION)
// We add a single timeline entry when our layout is fixed, and
// we don't know in advance when its contents might change.
.setTileTimeline(Timeline.fromLayoutElement(simpleLayout(this)))
.build()
return Futures.immediateFuture(tile)
}
設有時間限制的時間軸項目
您可以選擇使用 TimelineEntry
定義有效期間,資訊方塊就能在已知時間變更版面配置,不必要求應用程式推送新的資訊方塊。
此做法的經典示例,就是時間軸含有近期活動清單的議程資訊方塊。每個近期活動都設定了有效期間,指出顯示活動的時間。
資訊方塊 API 允許有效期間重疊。在這種情況下,系統會顯示剩餘期間最短的畫面。系統一次只會顯示一個事件。
開發人員可以提供預設的備用項目。舉例來說,議程資訊方塊可提供有效期間為無限期的資訊方塊,並用於沒有其他有效時間軸項目的情況,如以下程式碼範例所示:
override fun onTileRequest(
requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile?> {
val timeline = Timeline.Builder()
// Add fallback "no meetings" entry
// Use the version of TimelineEntry that's in androidx.wear.protolayout.
timeline.addTimelineEntry(
TimelineBuilders.TimelineEntry.Builder().setLayout(getNoMeetingsLayout()).build()
)
// Retrieve a list of scheduled meetings
val meetings = MeetingsRepo.getMeetings()
// Add a timeline entry for each meeting
meetings.forEach { meeting ->
timeline.addTimelineEntry(
TimelineBuilders.TimelineEntry.Builder()
.setLayout(getMeetingLayout(meeting))
.setValidity(
// The tile should disappear when the meeting begins
// Use the version of TimeInterval that's in
// androidx.wear.protolayout.
TimelineBuilders.TimeInterval.Builder()
.setEndMillis(meeting.dateTimeMillis)
.build()
)
.build()
)
}
val tile =
Tile.Builder()
.setResourcesVersion(RESOURCES_VERSION)
.setTileTimeline(timeline.build())
.build()
return Futures.immediateFuture(tile)
}
重新整理資訊方塊
資訊方塊顯示的資訊可能會在一段時間後失效。舉例來說,如果天氣資訊方塊整天都顯示相同溫度,就會不準確。
為處理失效的資料,請在建立資訊方塊時設定更新間隔,指定資訊方塊的有效時間長度。以天氣資訊方塊為例,您可以每小時更新一次內容,如下列程式碼範例所示:
override fun onTileRequest(
requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile?> =
Futures.immediateFuture(
Tile.Builder()
.setResourcesVersion(RESOURCES_VERSION)
.setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes
.setTileTimeline(Timeline.fromLayoutElement(getWeatherLayout()))
.build()
)
設定更新間隔後,系統會在間隔結束後隨即呼叫 onTileRequest()
。如果未設定更新間隔,系統就不會呼叫 onTileRequest()
。
資訊方塊也可能因外部事件而失效。例如使用者可能會從行事曆移除會議,如果資訊方塊並未重新整理,就仍會顯示已刪除的會議。在這種情況下,請在應用程式程式碼中的任意位置要求重新整理,如以下程式碼範例所示:
Kotlin
fun eventDeletedCallback() {
TileService.getUpdater(context)
.requestUpdate(MyTileService::class.java)
}
Java
public void eventDeletedCallback() {
TileService.getUpdater(context)
.requestUpdate(MyTileService.class);
}
選擇更新工作流程
運用下列最佳做法,決定如何設定資訊方塊更新:
- 如果是可預測的更新內容 (例如使用者日曆中的下一個活動),請使用時間軸。
- 擷取平台資料時,請使用資料繫結,讓系統自動更新資料。
如果能在短時間內於裝置端計算出更新內容 (例如在日出資訊方塊中更新圖片的位置),請使用 onTileRequest()
。
當您需要提早產生所有圖片時,這種做法特別實用。如果需要在未來產生新圖片,請呼叫 setFreshnessIntervalMillis()
。
如果會重複執行大量背景工作 (例如輪詢天氣資料),請使用 WorkManager
,並將更新內容推送至資訊方塊。
如果是回應外部事件 (例如開燈、接收電子郵件或更新記事) 的更新內容,請傳送 Firebase 雲端通訊 (FCM) 訊息再次啟動應用程式,然後將更新內容推送至資訊方塊。
如果資訊方塊資料同步程序可能會耗用大量資源,請執行以下操作:
- 排定資料同步處理作業。
- 啟動 1 到 2 秒的計時器。
- 如果在時間結束前收到遠端資料來源提供的更新內容,透過資料同步作業顯示更新後的值。否則,顯示快取的本機值。
為您推薦
這個頁面中的內容和程式碼範例均受《內容授權》中的授權所規範。Java 與 OpenJDK 是 Oracle 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-08-31 (世界標準時間)。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-08-31 (世界標準時間)。"],[],[],null,["Create tiles with content that changes as time passes.\n\nWork with timelines\n\nA timeline consists of one or more\n[`TimelineEntry`](/reference/androidx/wear/protolayout/TimelineBuilders.TimelineEntry)\ninstances, each of which contain a layout that is displayed during a specific\ntime interval. All tiles need a timeline.\n\nSingle-entry tiles\n\nOften a tile can be described with a single `TimelineEntry`. The layout is\nfixed, and only the information inside the layout changes. For example, a tile\nthat shows your fitness progress of the day always shows the same progress\nlayout, though you might adjust that layout to show different values. In these\ncases, you don't know in advance when the content might change.\n\nSee the following example of a tile with a single `TimelineEntry`: \n\n```kotlin\noverride fun onTileRequest(\n requestParams: RequestBuilders.TileRequest\n): ListenableFuture\u003cTile?\u003e {\n val tile =\n Tile.Builder()\n .setResourcesVersion(RESOURCES_VERSION)\n // We add a single timeline entry when our layout is fixed, and\n // we don't know in advance when its contents might change.\n .setTileTimeline(Timeline.fromLayoutElement(simpleLayout(this)))\n .build()\n return Futures.immediateFuture(tile)\n}https://github.com/android/snippets/blob/f95ab59fad80aeaf5d6a90bab8a01a126f20f44e/wear/src/main/java/com/example/wear/snippets/tile/Tile.kt#L74-L85\n```\n\nTimebound timeline entries\n\nA `TimelineEntry` can optionally define a validity period, allowing a tile to\nchange its layout at a known time without requiring the app to push a new tile.\n\nThe canonical example is an agenda tile whose timeline contains a list of\nupcoming events. Each upcoming event contains a validity period to indicate when\nto show it.\n\nThe tiles API allows for overlapping validity periods, where the screen with the\nshortest period of time left is the one shown. Only one event is displayed at a\ntime.\n\nDevelopers can provide a default fallback entry. For example, the agenda tile\ncould have a tile with an infinite validity period, which is used if no other\ntimeline entry is valid, as shown in the following code sample: \n\n```kotlin\noverride fun onTileRequest(\n requestParams: RequestBuilders.TileRequest\n): ListenableFuture\u003cTile?\u003e {\n val timeline = Timeline.Builder()\n\n // Add fallback \"no meetings\" entry\n // Use the version of TimelineEntry that's in androidx.wear.protolayout.\n timeline.addTimelineEntry(\n TimelineBuilders.TimelineEntry.Builder().setLayout(getNoMeetingsLayout()).build()\n )\n\n // Retrieve a list of scheduled meetings\n val meetings = MeetingsRepo.getMeetings()\n // Add a timeline entry for each meeting\n meetings.forEach { meeting -\u003e\n timeline.addTimelineEntry(\n TimelineBuilders.TimelineEntry.Builder()\n .setLayout(getMeetingLayout(meeting))\n .setValidity(\n // The tile should disappear when the meeting begins\n // Use the version of TimeInterval that's in\n // androidx.wear.protolayout.\n TimelineBuilders.TimeInterval.Builder()\n .setEndMillis(meeting.dateTimeMillis)\n .build()\n )\n .build()\n )\n }\n\n val tile =\n Tile.Builder()\n .setResourcesVersion(RESOURCES_VERSION)\n .setTileTimeline(timeline.build())\n .build()\n return Futures.immediateFuture(tile)\n}https://github.com/android/snippets/blob/f95ab59fad80aeaf5d6a90bab8a01a126f20f44e/wear/src/main/java/com/example/wear/snippets/tile/Tile.kt#L118-L154\n```\n\nRefresh a tile\n\nInformation shown on a tile might expire after some time. For example, a weather\ntile that shows the same temperature throughout the day isn't accurate.\n\nTo deal with expiring data, set a freshness interval at the time of creating a\ntile, which specifies how long the tile is valid. In the example of the weather\ntile, you might update its content every hour, as shown in the following code\nsample: \n\n```kotlin\noverride fun onTileRequest(\n requestParams: RequestBuilders.TileRequest\n): ListenableFuture\u003cTile?\u003e =\n Futures.immediateFuture(\n Tile.Builder()\n .setResourcesVersion(RESOURCES_VERSION)\n .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes\n .setTileTimeline(Timeline.fromLayoutElement(getWeatherLayout()))\n .build()\n )https://github.com/android/snippets/blob/f95ab59fad80aeaf5d6a90bab8a01a126f20f44e/wear/src/main/java/com/example/wear/snippets/tile/Tile.kt#L162-L171\n```\n\nWhen you set a freshness interval, the system calls\n[`onTileRequest()`](/reference/androidx/wear/tiles/TileService#onTileRequest(androidx.wear.tiles.RequestBuilders.TileRequest))\nshortly after the interval finishes. If you don't set a freshness interval, the\nsystem doesn't call `onTileRequest()`.\n\nA tile can also expire because of an external event. For example, a user might\nremove a meeting from their calendar, and if the tile wasn't refreshed, then the\ntile would still show that deleted meeting. In this case, request a refresh from\nany place in your application code, as shown in the following code sample: \n\nKotlin \n\n```kotlin\nfun eventDeletedCallback() {\n TileService.getUpdater(context)\n .requestUpdate(MyTileService::class.java)\n}\n```\n\nJava \n\n```java\npublic void eventDeletedCallback() {\n TileService.getUpdater(context)\n .requestUpdate(MyTileService.class);\n}\n```\n\nChoose an update workflow\n\nUse these best practices to determine how to configure your tile updates:\n\n- If the update is predictable---for example, if it's for the next event in the user's calendar---use a timeline.\n- When you fetch platform data, use data binding so that the system updates the data automatically.\n- If the update can be calculated on-device in a small amount of time---such\n as updating the position of an image on a sunrise tile---use\n [`onTileRequest()`](/reference/androidx/wear/tiles/TileService#onTileRequest(androidx.wear.tiles.RequestBuilders.TileRequest)).\n\n This is particularly useful when you need to generate all images ahead of\n time. If you need to generate a new image at a future time, call\n [`setFreshnessIntervalMillis()`](/reference/androidx/wear/tiles/TileBuilders.Tile.Builder#setFreshnessIntervalMillis(long)).\n- If you're doing more intensive background work repeatedly, such as polling\n for weather data, use [`WorkManager`](/topic/libraries/architecture/workmanager), and push updates to your tile.\n\n- If the update is in response to an external event---such as the lights\n turning on, receiving an email, or updating a note---send a [Firebase Cloud\n Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging) message to make your app active again, then push updates\n to the tile.\n\n- If the tile data sync process might be expensive, do the following:\n\n 1. Schedule a data sync.\n 2. Start a timer for 1-2 seconds.\n 3. If you receive an update from a remote data source before time runs out, show the updated value from the data sync. Otherwise, show a cached local value.\n\nRecommended for you\n\n- Note: link text is displayed when JavaScript is off\n- [Minimize the effect of regular updates](/develop/connectivity/minimize-effect-regular-updates)\n- [Access location in the background](/develop/sensors-and-location/location/background)\n- [Getting started with WorkManager](/develop/background-work/background-tasks/persistent/getting-started)"]]