From bf7094d616ab697fc97776dc4c965d4410797063 Mon Sep 17 00:00:00 2001 From: Me7c7 Date: Wed, 1 Oct 2025 21:31:21 +0300 Subject: [PATCH] Huawei: fix send GPS and time data. It is used to calculate the correct moon and sun data on the watch. It can also be used to speed up the GPS. --- .../activities/SettingsActivity.java | 4 +- .../devices/huawei/HuaweiCoordinator.java | 4 ++ .../devices/huawei/packets/GpsAndTime.java | 4 +- .../devices/huawei/HuaweiWeatherManager.java | 37 +++++++++++++++++-- .../SendGpsAndTimeToDeviceRequest.java | 20 +++++++--- .../pebble/webview/CurrentPosition.java | 2 +- app/src/main/res/values/strings.xml | 2 + .../devicesettings_huawei_gps_and_time.xml | 11 ++++++ 8 files changed, 70 insertions(+), 14 deletions(-) create mode 100644 app/src/main/res/xml/devicesettings_huawei_gps_and_time.xml diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java index c60cbf7bda..8d5ba7caa4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java @@ -123,8 +123,8 @@ public class SettingsActivity extends AbstractSettingsActivityV2 { index(R.xml.automations_settings, R.string.pref_header_automations); setInputTypeFor("rtl_max_line_length", InputType.TYPE_CLASS_NUMBER); - setInputTypeFor("location_latitude", InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED); - setInputTypeFor("location_longitude", InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED); + setInputTypeFor("location_latitude", InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED | InputType.TYPE_NUMBER_FLAG_DECIMAL); + setInputTypeFor("location_longitude", InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED | InputType.TYPE_NUMBER_FLAG_DECIMAL); Prefs prefs = GBApplication.getPrefs(); Preference pref = findPreference("pref_category_activity_personal"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiCoordinator.java index c22974ebeb..69e911eaee 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiCoordinator.java @@ -395,6 +395,8 @@ public class HuaweiCoordinator { // Developer final List developer = deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.DEVELOPER); developer.add(R.xml.devicesettings_huawei_debug); + if(supportsGpsAndTimeToDevice()) + developer.add(R.xml.devicesettings_huawei_gps_and_time); return deviceSpecificSettings; } @@ -652,6 +654,8 @@ public class HuaweiCoordinator { return supportsCommandForService(0x18, 0x02); } + public boolean supportsGpsAndTimeToDevice() { return supportsCommandForService(0x18, 0x06); } + public boolean supportsAccount() { return supportsCommandForService(0x1A, 0x01); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/GpsAndTime.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/GpsAndTime.java index d2b1c16732..a1d5754ac2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/GpsAndTime.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/GpsAndTime.java @@ -229,8 +229,8 @@ public class GpsAndTime { this.commandId = id; this.tlv = new HuaweiTLV() .put(0x01, timestamp) - .put(0x02, lon) - .put(0x03, lat); + .put(0x02, lat) + .put(0x03, lon); this.isEncrypted = true; this.complete = true; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiWeatherManager.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiWeatherManager.java index 9e445aeb61..3192cf470f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiWeatherManager.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiWeatherManager.java @@ -16,14 +16,19 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei; +import android.location.Location; import android.widget.Toast; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Calendar; import java.util.Date; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; @@ -38,6 +43,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.Send import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherSunMoonSupportRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherSupportRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherUnitRequest; +import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.webview.CurrentPosition; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; @@ -169,6 +175,8 @@ public class HuaweiWeatherManager { } for (WeatherSpec.Daily point : weatherSpec.getForecasts()) { + if(point == null) + continue; currentDay = nextDay; nextDay = DateTimeUtils.shiftByDays(currentDay, 1); @@ -191,6 +199,14 @@ public class HuaweiWeatherManager { } } + private BigDecimal toBigDecimal(double d2) { + try { + return new BigDecimal(d2); + } catch (NumberFormatException unused) { + return null; + } + } + public void sendWeather(WeatherSpec weatherSpec) { // Initialize weather settings and send weather if (!supportProvider.getHuaweiCoordinator().supportsWeather()) { @@ -250,10 +266,23 @@ public class HuaweiWeatherManager { lastRequest.nextRequest(sendWeatherCurrentRequest); lastRequest = sendWeatherCurrentRequest; - SendGpsAndTimeToDeviceRequest sendGpsAndTimeToDeviceRequest = new SendGpsAndTimeToDeviceRequest(supportProvider); - sendGpsAndTimeToDeviceRequest.setFinalizeReq(errorHandler); - lastRequest.nextRequest(sendGpsAndTimeToDeviceRequest); - lastRequest = sendGpsAndTimeToDeviceRequest; + + if (supportProvider.getHuaweiCoordinator().supportsGpsAndTimeToDevice() && + GBApplication.getDevicePrefs(supportProvider.getDevice()).getBoolean("pref_huawei_gps_and_time", true)) { + Location location = new CurrentPosition().getLastKnownLocation(); + BigDecimal latitude = toBigDecimal(location.getLatitude()); + BigDecimal longitude = toBigDecimal(location.getLongitude()); + if (latitude != null && longitude != null) { + double lat = latitude.setScale(7, RoundingMode.HALF_UP).doubleValue(); + double lon = longitude.setScale(7, RoundingMode.HALF_UP).doubleValue(); + //TODO: should be timestamp when location is set, set old enough to prevent override location determined by workout + int timestamp = (int) (Calendar.getInstance().getTime().getTime() / 1000L) - 86400; + SendGpsAndTimeToDeviceRequest sendGpsAndTimeToDeviceRequest = new SendGpsAndTimeToDeviceRequest(supportProvider, timestamp, lat, lon); + sendGpsAndTimeToDeviceRequest.setFinalizeReq(errorHandler); + lastRequest.nextRequest(sendGpsAndTimeToDeviceRequest); + lastRequest = sendGpsAndTimeToDeviceRequest; + } + } if (supportProvider.getHuaweiCoordinator().supportsWeatherForecasts()) { SendWeatherForecastRequest sendWeatherForecastRequest = new SendWeatherForecastRequest(supportProvider, weatherSettings, weatherSpec); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendGpsAndTimeToDeviceRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendGpsAndTimeToDeviceRequest.java index 271299de8f..5d433a8b23 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendGpsAndTimeToDeviceRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendGpsAndTimeToDeviceRequest.java @@ -19,31 +19,41 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests; import android.location.Location; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigDecimal; import java.util.Calendar; import java.util.List; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.GpsAndTime; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.p2p.HuaweiP2PContactsService; import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.webview.CurrentPosition; public class SendGpsAndTimeToDeviceRequest extends Request { + private final int timestamp; + private final double lat; + private final double lon; - public SendGpsAndTimeToDeviceRequest(HuaweiSupportProvider support) { + public SendGpsAndTimeToDeviceRequest(HuaweiSupportProvider support, int timestamp, double lat, double lon) { super(support); this.serviceId = GpsAndTime.id; this.commandId = GpsAndTime.CurrentGPSRequest.id; + this.timestamp = timestamp; + this.lat = lat; + this.lon = lon; } @Override protected List createRequest() throws RequestCreationException { try { - Location location = new CurrentPosition().getLastKnownLocation(); return new GpsAndTime.CurrentGPSRequest( this.paramsProvider, - (int) (Calendar.getInstance().getTime().getTime() / 1000L) - 60, // Backdating a bit seems to work better - location.getLatitude(), - location.getLongitude() + timestamp, + lat, + lon ).serialize(); } catch (HuaweiPacket.CryptoException e) { throw new RequestCreationException(e); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/CurrentPosition.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/CurrentPosition.java index f805ef4cef..2db5f39120 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/CurrentPosition.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/webview/CurrentPosition.java @@ -62,7 +62,7 @@ public class CurrentPosition { lastKnownLocation.setLatitude(this.latitude); lastKnownLocation.setLongitude(this.longitude); - LOG.info("got longitude/latitude from preferences: " + latitude + "/" + longitude); + LOG.info("got longitude/latitude from preferences: {}/{}", latitude, longitude); this.timestamp = System.currentTimeMillis() - 86400000; //let accessor know this value is really old diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 71cd1f2a18..6d5c11286d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4352,4 +4352,6 @@ Rotate screen Filter charts Recovery Heart rate + Send GPS and Time to device + Send GPS and Time to device for weather and search stars optimization. Location should be set in the settings diff --git a/app/src/main/res/xml/devicesettings_huawei_gps_and_time.xml b/app/src/main/res/xml/devicesettings_huawei_gps_and_time.xml new file mode 100644 index 0000000000..2214b93fcf --- /dev/null +++ b/app/src/main/res/xml/devicesettings_huawei_gps_and_time.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file