如何向 Android Wear TileService 发送数据
Posted
技术标签:
【中文标题】如何向 Android Wear TileService 发送数据【英文标题】:How to send data to Android Wear TileService 【发布时间】:2021-12-19 21:07:37 【问题描述】:我真的不知道如何为我的 Wear OS 磁贴提供数据。目前,我正在尝试从 BroadcastReceiver 接收我的心率,它可以工作,但我的值在 onTileRequest 中始终为 0。
这是我的 TileService...
public class HeartRateTileService extends TileService
private static final String RESOURCES_VERSION = "1";
private String currentHeartrate = "0";
@Override //onStartCommand never gets called
public int onStartCommand(Intent intent, int flags, int startId)
int i = super.onStartCommand(intent, flags, startId);
Log.d("HeartRate", "onStartCommand " + currentHeartrate);
LocalBroadcastManager.getInstance(this).registerReceiver(messageReceiver, new IntentFilter("heart-rate-to-activity"));
return i;
@Override
public void onCreate()
super.onCreate();
LocalBroadcastManager.getInstance(this).registerReceiver(messageReceiver, new IntentFilter("heart-rate-to-activity"));
@NonNull
@Override
protected ListenableFuture<TileBuilders.Tile> onTileRequest(
@NonNull RequestBuilders.TileRequest requestParams
)
Log.d("HeartRate", "onTileRequest " + currentHeartrate);
return Futures.immediateFuture(new TileBuilders.Tile.Builder()
.setResourcesVersion(RESOURCES_VERSION)
.setFreshnessIntervalMillis(1000*60)
.setTimeline(new TimelineBuilders.Timeline.Builder()
.addTimelineEntry(new TimelineBuilders.TimelineEntry.Builder()
.setLayout(new LayoutElementBuilders.Layout.Builder()
.setRoot(
layout()
).build()
).build()
).build()
).build()
);
private LayoutElementBuilders.LayoutElement layout()
return new LayoutElementBuilders.Row.Builder()
.setWidth(wrap())
.setHeight(expand())
.setVerticalAlignment(LayoutElementBuilders.VERTICAL_ALIGN_CENTER)
.addContent(new LayoutElementBuilders.Text.Builder()
.setText(currentHeartrate)
.build()
).build();
@NonNull
@Override
protected ListenableFuture<ResourceBuilders.Resources> onResourcesRequest(
@NonNull RequestBuilders.ResourcesRequest requestParams
)
Log.d("HeartRate", "onResourcesRequest " + currentHeartrate);
return Futures.immediateFuture(new ResourceBuilders.Resources.Builder()
.setVersion(RESOURCES_VERSION)
.build()
);
private final BroadcastReceiver messageReceiver = new BroadcastReceiver()
@Override
public void onReceive(Context context, Intent intent)
Log.d("HeartRate", "message: " + currentHeartrate);
currentHeartrate = intent.getExtras().getString("message");
;
这就是我得到的... 如您所见,onTileRequest 始终为 0。可能是因为每当调用 onTileRequest 时也会调用 onCreate,因此此时我的数据为 0。但是我怎样才能永久保存心率呢?难道我做错了什么?或者瓷砖只是不打算接收广播接收器的数据。还有其他方法吗?我真的没有发现任何关于使用互联网上的数据更新磁贴的信息。
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 2
D/HeartRate: onCreate 0
W/t.myapplicatio: Accessing hidden field Ljava/nio/Buffer;->address:J (light greylist, reflection)
D/HeartRate: onTileRequest 0
D/HeartRate: onResourcesRequest 0
D/ViewRootImpl[MainActivity]: changeCanvasOpacity: opaque=false
D/HeartRate: onCreate 0
D/HeartRate: message: 0
D/HeartRate: message: 0
D/HeartRate: message: 81
D/HeartRate: message: 81
D/HeartRate: onCreate 0
D/HeartRate: message: 81
message: 81
message: 0
D/HeartRate: message: 81
I/chatty: uid=10096(com.pezcraft.myapplication) identical 1 line
D/HeartRate: message: 82
D/HeartRate: message: 72
I/chatty: uid=10096(com.pezcraft.myapplication) identical 1 line
D/HeartRate: message: 72
D/HeartRate: message: 73
I/chatty: uid=10096(com.pezcraft.myapplication) identical 1 line
D/HeartRate: message: 73
D/HeartRate: onCreate 0
D/HeartRate: onTileRequest 0
D/HeartRate: message: 75
I/chatty: uid=10096(com.pezcraft.myapplication) identical 1 line
D/HeartRate: message: 75
message: 0
D/HeartRate: message: 75
I/chatty: uid=10096(com.pezcraft.myapplication) identical 2 lines
D/HeartRate: message: 75
【问题讨论】:
【参考方案1】:TileService 的生命周期与您的应用程序不同。您的磁贴服务可能会被销毁,并为其他请求创建一个新服务。接收到心跳传感器数据时,为生成磁贴而创建的服务可能不太可能处于唤醒状态。
android Widgets https://twitter.com/marxallski/status/1454889465206513667 上的此线程也适用于 Wear Tiles 和 Complications。
理想情况下,数据缓存在内存中,如果没有,请使用 worker 刷新它,每当缓存数据时,它应该通知小部件更新。
您不应该将数据保存在 GlanceAppWidget 中,它应该保存在应用程序范围内
这里也一样。
您的 tile 应该非常快速、有效地无状态地执行
未发起可能较长或失败的网络请求,或订阅后台数据 返回缓存在内存中(应用程序范围)或从数据库(房间?)读取的数据尝试订阅磁贴外的数据。存储与应用程序相关的数据(Application 子类中的一个字段),使用 Koin/Hilt 之类的 DI,或者存储在您收到 onTileRequest 请求时可以读取的数据库中。
我对健康数据或广播不是很熟悉 - 但这似乎很相关https://developer.android.com/training/wearables/health-services/passive
【讨论】:
以上是关于如何向 Android Wear TileService 发送数据的主要内容,如果未能解决你的问题,请参考以下文章
与 Android Wear 的 React-Native 通信