Fossil/Skagen Hybrids: Add sending calendar items

This commit is contained in:
Arjan Schrijver 2025-02-28 21:24:37 +01:00
parent 7141e2d592
commit e7408099a4
3 changed files with 88 additions and 1 deletions

View File

@ -229,6 +229,11 @@ public class QHybridCoordinator extends AbstractBLEDeviceCoordinator {
return true;
}
@Override
public boolean supportsCalendarEvents() {
return isHybridHR();
}
@Override
protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
@ -267,6 +272,7 @@ public class QHybridCoordinator extends AbstractBLEDeviceCoordinator {
// Settings applicable to all firmware versions
generic.add(R.xml.devicesettings_fossilhybridhr_calibration);
generic.add(R.xml.devicesettings_fossilhybridhr_navigation);
generic.add(R.xml.devicesettings_sync_calendar);
final List<Integer> health = deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.HEALTH);
health.add(R.xml.devicesettings_fossilhybridhr_workout_detection);
health.add(R.xml.devicesettings_inactivity);

View File

@ -55,6 +55,7 @@ import nodomain.freeyourgadget.gadgetbridge.externalevents.NotificationListener;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
@ -851,4 +852,14 @@ public class QHybridSupport extends QHybridBaseSupport {
public void onSetNavigationInfo(NavigationInfoSpec navigationInfoSpec) {
((FossilHRWatchAdapter) watchAdapter).onSetNavigationInfo(navigationInfoSpec);
}
@Override
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {
((FossilHRWatchAdapter) watchAdapter).onSendCalendar();
}
@Override
public void onDeleteCalendarEvent(byte type, long id) {
((FossilHRWatchAdapter) watchAdapter).onSendCalendar();
}
}

View File

@ -78,7 +78,10 @@ import java.nio.charset.StandardCharsets;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -105,9 +108,9 @@ import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.HybridHRActivitySamp
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.HybridHRSpo2SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationHRConfiguration;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.entities.User;
import nodomain.freeyourgadget.gadgetbridge.entities.HybridHRActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.HybridHRSpo2Sample;
import nodomain.freeyourgadget.gadgetbridge.entities.User;
import nodomain.freeyourgadget.gadgetbridge.externalevents.NotificationListener;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
@ -181,9 +184,12 @@ import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
import nodomain.freeyourgadget.gadgetbridge.util.UriHelper;
import nodomain.freeyourgadget.gadgetbridge.util.Version;
import nodomain.freeyourgadget.gadgetbridge.util.calendar.CalendarEvent;
import nodomain.freeyourgadget.gadgetbridge.util.calendar.CalendarManager;
public class FossilHRWatchAdapter extends FossilWatchAdapter {
public static final int MESSAGE_WHAT_VOICE_DATA_RECEIVED = 0;
private static final int MAX_CALENDAR_ITEMS = 10;
private byte[] phoneRandomNumber;
private byte[] watchRandomNumber;
@ -215,6 +221,8 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
private Version cleanFirmwareVersion = null;
private final Set<CalendarEvent> lastSync = new HashSet<>();
ServiceConnection voiceServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
@ -1609,6 +1617,68 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
}
}
public void onSendCalendar() {
if (!getDeviceSpecificPreferences().getBoolean("sync_calendar", false)) {
LOG.debug("Ignoring calendar sync request, sync is disabled");
return;
}
final CalendarManager upcomingEvents = new CalendarManager(getContext(), getDeviceSupport().getDevice().getAddress());
final List<CalendarEvent> calendarEvents = upcomingEvents.getCalendarEventList();
final Set<CalendarEvent> thisSync = new HashSet<>();
int nEvents = 0;
for (final CalendarEvent calendarEvent : calendarEvents) {
if (++nEvents > MAX_CALENDAR_ITEMS) {
LOG.warn("Syncing only first {} events of {}", MAX_CALENDAR_ITEMS, calendarEvents.size());
break;
}
thisSync.add(calendarEvent);
}
if (thisSync.equals(lastSync)) {
LOG.debug("Already synced this set of events, won't send to device");
return;
}
lastSync.clear();
lastSync.addAll(thisSync);
List<CalendarEvent> sortedEventList = new ArrayList<>(thisSync);
Collections.sort(sortedEventList, Comparator.comparingLong(CalendarEvent::getBegin));
LOG.debug("Syncing {} calendar events", sortedEventList.size());
try {
JSONArray items = new JSONArray();
for(CalendarEvent event : sortedEventList) {
JSONArray reminders = new JSONArray();
for (long reminder : event.getRemindersAbsoluteTs()) {
reminders.put(reminder / 1000);
}
items.put(new JSONObject()
.put("id", event.getId())
.put("title", event.getTitle())
.put("desc", event.getDescription())
.put("start", event.getBeginSeconds())
.put("end", event.getEndSeconds())
.put("reminders", reminders)
);
}
JSONObject calendarObj = new JSONObject()
.put("res", new JSONObject()
.put("set", new JSONObject()
.put("calendarApp._.config.events", items)
)
);
queueWrite(new JsonPutRequest(calendarObj, this));
} catch (JSONException e) {
LOG.error("Error sending calendar events: ", e);
}
}
@Override
public void factoryReset() {
queueWrite(new FactoryResetRequest());