Tạo thẻ thông tin có nội dung thay đổi khi thời gian trôi qua.
Làm việc với dòng thời gian
Dòng thời gian bao gồm một hoặc nhiều thực thể TimelineEntry
, mỗi thực thể chứa một bố cục được hiển thị trong khoảng thời gian cụ thể. Tất cả các thẻ thông tin đều cần có dòng thời gian.
Thẻ thông tin gồm một mục nhập
Thông thường, bạn có thể mô tả thẻ thông tin bằng một TimelineEntry
. Bố cục này là cố định và chỉ thông tin bên trong bố cục đó sẽ thay đổi. Ví dụ: một thẻ thông tin hiện tiến trình bạn tập thể dục trong ngày sẽ luôn hiện cùng một bố cục tiến trình, mặc dù bạn có thể điều chỉnh bố cục đó để hiện nhiều giá trị. Trong những trường hợp này, bạn không biết trước thời điểm nội dung có thể thay đổi.
Hãy xem ví dụ sau đây về thẻ thông tin có một TimelineEntry
:
Kotlin
override fun onTileRequest( requestParams: 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(...) ).build() return Futures.immediateFuture(tile) }
Java
@Override protected ListenableFuture<Tile> onTileRequest( @NonNull TileRequest requestParams ) { Tile tile = new 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(...) ).build(); return Futures.immediateFuture(tile); }
Mục nhập dòng thời gian có thời hạn
Một TimelineEntry
có thể tuỳ ý xác định khoảng thời gian hợp lệ, cho phép thẻ thông tin thay đổi bố cục tại thời điểm xác định mà không yêu cầu ứng dụng đẩy một thẻ thông tin mới.
Ví dụ chuẩn là một thẻ thông tin cho chương trình làm việc có dòng thời gian chứa danh sách các sự kiện sắp tới. Mỗi sự kiện sắp tới chứa một khoảng thời gian hiệu lực để cho biết thời điểm sẽ hiện sự kiện đó.
API thẻ thông tin cho phép các khoảng thời gian hiệu lực chồng chéo, trong đó màn hình có khoảng thời gian còn lại ngắn nhất là màn hình hiển thị. Tại mỗi thời điểm, chỉ có một sự kiện hiển thị.
Nhà phát triển có thể cung cấp một mục nhập dự phòng mặc định. Ví dụ: tệp thông tin cho chương trình làm việc có thể có một tệp thông tin có thời gian hiệu lực vô hạn, được dùng nếu không có mục nhập dòng thời gian nào khác hợp lệ, như trong mã mẫu sau:
Kotlin
public override fun onTileRequest( requestParams: 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(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(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. TimeInterval.Builder() .setEndMillis(meeting.dateTimeMillis).build() ).build() ) } val tile = Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline(timeline.build()) .build() return Futures.immediateFuture(tile) }
Java
@Override protected ListenableFuture<Tile> onTileRequest( @NonNull RequestBuilders.TileRequest requestParams ) { Timeline.Builder timeline = new Timeline.Builder(); // Add fallback "no meetings" entry // Use the version of TimelineEntry that's in androidx.wear.protolayout. timeline.addTimelineEntry(new TimelineEntry.Builder().setLayout(getNoMeetingsLayout()).build()); // Retrieve a list of scheduled meetings List<Meeting> meetings = MeetingsRepo.getMeetings(); // Add a timeline entry for each meeting for(Meeting meeting : meetings) { timeline.addTimelineEntry(new 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. new TimeInterval.builder() .setEndMillis(meeting.getDateTimeMillis()).build() ).build() ); } Tile tile = new Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline(timeline.build()) .build(); return Futures.immediateFuture(tile); }
Làm mới thẻ thông tin
Thông tin hiển thị trên thẻ thông tin có thể hết hạn sau một khoảng thời gian. Ví dụ: một thẻ thông tin thời tiết là không chính xác nếu hiển thị cùng một nhiệt độ trong suốt cả ngày.
Để xử lý dữ liệu sắp hết hạn, hãy đặt khoảng thời gian làm mới tại thời điểm tạo thẻ thông tin. Khoảng thời gian này xác định thẻ thông tin có hiệu lực trong bao lâu. Trong ví dụ về thẻ thông tin thời tiết, bạn có thể cập nhật nội dung của thẻ này mỗi giờ như trong mã mẫu sau đây:
Kotlin
override fun onTileRequest(requestParams: RequestBuilders.TileRequest) = Futures.immediateFuture(Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes .setTileTimeline(Timeline.fromLayoutElement( getWeatherLayout()) ).build() )
Java
@Override protected ListenableFuture<Tile> onTileRequest( @NonNull TileRequest requestParams ) { return Futures.immediateFuture(new Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes .setTimeline(Timeline.fromLayoutElement( getWeatherLayout()) ).build()); }
Khi bạn đặt một khoảng thời gian làm mới, hệ thống sẽ gọi onTileRequest()
ngay sau khi khoảng thời gian này kết thúc. Nếu bạn không đặt khoảng thời gian làm mới thì hệ thống sẽ không gọi onTileRequest()
.
Thẻ thông tin cũng có thể hết hạn do sự kiện bên ngoài. Ví dụ: người dùng có thể xoá một cuộc họp khỏi lịch của mình và nếu không được làm mới, thẻ thông tin sẽ vẫn hiển thị cuộc họp đã xoá đó. Trong trường hợp này, hãy yêu cầu làm mới từ vị trí bất kỳ trong mã xử lý ứng dụng của bạn, như trong mã mẫu sau:
Kotlin
fun eventDeletedCallback() { TileService.getUpdater(context) .requestUpdate(MyTileService::class.java) }
Java
public void eventDeletedCallback() { TileService.getUpdater(context) .requestUpdate(MyTileService.class); }
Chọn quy trình cập nhật
Hãy làm theo các phương pháp hay nhất sau đây để xác định cách định cấu hình nội dung cập nhật cho thẻ thông tin của bạn:
- Nếu nội dung cập nhật có thể dự đoán được (ví dụ: sự kiện tiếp theo trong lịch của người dùng), hãy sử dụng dòng thời gian.
- Khi bạn tìm nạp dữ liệu nền tảng, hãy sử dụng tính năng liên kết dữ liệu để hệ thống tự động cập nhật dữ liệu.
Nếu có thể tính toán nội dung cập nhật trên thiết bị trong một khoảng thời gian ngắn (chẳng hạn như cập nhật vị trí của một hình ảnh trên thẻ thông tin mặt trời mọc), hãy sử dụng
onTileRequest()
.Điều này đặc biệt hữu ích khi bạn cần tạo trước tất cả các hình ảnh. Nếu bạn cần tạo hình ảnh mới vào một thời điểm trong tương lai, hãy gọi
setFreshnessIntervalMillis()
.Nếu bạn đang lặp đi lặp lại một nhiệm vụ cần nhiều tài nguyên hơn ở chế độ nền (chẳng hạn như kiểm tra dữ liệu thời tiết), hãy sử dụng
WorkManager
và đẩy nội dung cập nhật vào thẻ thông tin.Nếu nội dung cập nhật phản hồi một sự kiện bên ngoài (chẳng hạn như bật đèn, nhận email hoặc cập nhật ghi chú), hãy gửi thông báo bằng Giải pháp gửi thông báo qua đám mây của Firebase (FCM) để kích hoạt lại ứng dụng, sau đó đẩy nội dung cập nhật vào thẻ thông tin.
Nếu quá trình đồng bộ hoá dữ liệu thẻ thông tin có thể sẽ rất tốn kém, hãy làm như sau:
- Lên lịch đồng bộ hoá dữ liệu.
- Bắt đầu hẹn giờ trong 1 – 2 giây.
- Nếu bạn nhận được nội dung cập nhật từ một nguồn dữ liệu từ xa trước khi hết thời gian, hãy hiện giá trị đã cập nhật từ quá trình đồng bộ hoá dữ liệu. Nếu không, hãy hiện một giá trị được lưu vào bộ nhớ đệm trên máy.
Đề xuất cho bạn
- Lưu ý: văn bản có đường liên kết sẽ hiện khi JavaScript tắt
- Giảm thiểu tác động của bản cập nhật định kỳ
- Truy cập thông tin vị trí khi ở chế độ nền
- Làm quen với WorkManager