From fa20bf66c65187b8177040d57b1740e6390d1849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sun, 5 Nov 2023 19:03:38 +0000 Subject: [PATCH] Mi Band 8: Fix send gps location during workout --- .../xiaomi/services/XiaomiHealthService.java | 36 +++++++++++++------ app/src/main/proto/xiaomi.proto | 2 +- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiHealthService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiHealthService.java index a27508130..5f8bd59d6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiHealthService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/services/XiaomiHealthService.java @@ -425,7 +425,13 @@ public class XiaomiHealthService extends AbstractXiaomiService { } private void handleWorkoutOpen(final XiaomiProto.WorkoutOpenWatch workoutOpenWatch) { - LOG.debug("Workout open on watch: {}", workoutOpenWatch.getSport()); + LOG.debug( + "Workout open on watch: {}, workoutStarted={}, gpsStarted={}, gpsFixAcquired={}", + workoutOpenWatch.getSport(), + workoutStarted, + gpsStarted, + gpsFixAcquired + ); workoutStarted = false; @@ -455,7 +461,12 @@ public class XiaomiHealthService extends AbstractXiaomiService { gpsTimeoutHandler.removeCallbacksAndMessages(null); // Timeout if the watch stops sending workout open - gpsTimeoutHandler.postDelayed(() -> GBLocationManager.stop(getSupport().getContext(), getSupport()), 5000); + gpsTimeoutHandler.postDelayed(() -> { + LOG.debug("Timed out waiting for workout"); + gpsStarted = false; + gpsFixAcquired = false; + GBLocationManager.stop(getSupport().getContext(), getSupport()); + }, 5000); } private void handleWorkoutStatus(final XiaomiProto.WorkoutStatusWatch workoutStatus) { @@ -475,6 +486,8 @@ public class XiaomiHealthService extends AbstractXiaomiService { case WORKOUT_PAUSED: break; case WORKOUT_FINISHED: + gpsStarted = false; + gpsFixAcquired = false; GBLocationManager.stop(getSupport().getContext(), getSupport()); if (startOnPhone) { OpenTracksController.stopRecording(getSupport().getContext()); @@ -495,26 +508,29 @@ public class XiaomiHealthService extends AbstractXiaomiService { XiaomiProto.WorkoutOpenReply.newBuilder() .setUnknown1(0) .setUnknown2(2) - .setUnknown3(10) + .setUnknown3(2) )) .build() ); } - + if (workoutStarted) { final XiaomiProto.WorkoutLocation.Builder workoutLocation = XiaomiProto.WorkoutLocation.newBuilder() - .setNumSatellites(10) + .setUnknown1(2) .setTimestamp((int) (location.getTime() / 1000L)) .setLongitude(location.getLongitude()) .setLatitude(location.getLatitude()) .setAltitude(location.getAltitude()) .setSpeed(location.getSpeed()) - .setBearing(location.getBearing()) - .setHorizontalAccuracy(location.getAccuracy()); + .setBearing(location.getBearing()); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - workoutLocation.setVerticalAccuracy(location.getVerticalAccuracyMeters()); - } + // FIXME: Check the value for these during actual workouts, but it seems to work without them + //if (location.hasAccuracy() && location.getAccuracy() != 100) { + // workoutLocation.setHorizontalAccuracy(location.getAccuracy()); + //} + //if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && location.hasVerticalAccuracy() && location.getVerticalAccuracyMeters() != 100) { + // workoutLocation.setVerticalAccuracy(location.getVerticalAccuracyMeters()); + //} getSupport().sendCommand( "send gps location", diff --git a/app/src/main/proto/xiaomi.proto b/app/src/main/proto/xiaomi.proto index 5ddc8dd7d..51a6934d0 100644 --- a/app/src/main/proto/xiaomi.proto +++ b/app/src/main/proto/xiaomi.proto @@ -485,7 +485,7 @@ message WorkoutOpenReply { } message WorkoutLocation { - optional uint32 numSatellites = 1; // 10, sometimes 2? + optional uint32 unknown1 = 1; // 10, sometimes 2? optional uint32 timestamp = 2; // seconds optional double longitude = 3; optional double latitude = 4;