【问题标题】:How to send data to Android Wear TileService如何向 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

【问题讨论】:

    标签: java android wear-os android-wear-2.0 wear-os-tiles


    【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      相关资源
      最近更新 更多