diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/CalendarReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/CalendarReceiver.java
new file mode 100644
index 000000000..b09435a05
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/CalendarReceiver.java
@@ -0,0 +1,143 @@
+/* Copyright (C) 2016-2017 Andreas Shimokawa, Daniele Gobbetti
+
+ This file is part of Gadgetbridge.
+
+ Gadgetbridge is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gadgetbridge is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see . */
+package nodomain.freeyourgadget.gadgetbridge.externalevents;
+
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+
+import nodomain.freeyourgadget.gadgetbridge.BuildConfig;
+import nodomain.freeyourgadget.gadgetbridge.GBApplication;
+import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
+import nodomain.freeyourgadget.gadgetbridge.model.CalendarEvents;
+
+public class CalendarReceiver extends BroadcastReceiver {
+ private static final Logger LOG = LoggerFactory.getLogger(CalendarReceiver.class);
+ private static Hashtable eventState = new Hashtable<>();
+
+ private class EventSyncState {
+ private EventState state;
+ private CalendarEvents.CalendarEvent event;
+
+ public EventSyncState(CalendarEvents.CalendarEvent event, EventState state) {
+ this.state = state;
+ this.event = event;
+ }
+
+ public EventState getState() {
+ return state;
+ }
+
+ public void setState(EventState state) {
+ this.state = state;
+ }
+
+ public CalendarEvents.CalendarEvent getEvent() {
+ return event;
+ }
+
+ public void setEvent(CalendarEvents.CalendarEvent event) {
+ this.event = event;
+ }
+ }
+
+ private enum EventState {
+ NOT_SYNCED, SYNCED, NEEDS_UPDATE, NEEDS_DELETE
+ }
+
+ public CalendarReceiver() {
+ LOG.info("Created calendar receiver.");
+ Context context = GBApplication.getContext();
+ Intent intent = new Intent("CALENDAR_SYNC");
+ intent.setPackage(BuildConfig.APPLICATION_ID);
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, new Intent("CALENDAR_SYNC"), 0);
+ AlarmManager am = (AlarmManager) (context.getSystemService(Context.ALARM_SERVICE));
+
+ am.setInexactRepeating(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis() + 10000, AlarmManager.INTERVAL_HALF_HOUR, pendingIntent);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ LOG.info("Syncing with calendar.");
+ List eventList = (new CalendarEvents()).getCalendarEventList(GBApplication.getContext());
+ Hashtable eventTable = new Hashtable<>();
+
+ for (CalendarEvents.CalendarEvent e: eventList) {
+ eventTable.put(e.getId(), e);
+ if (!eventState.containsKey(e.getId())) {
+ eventState.put(e.getId(), new EventSyncState(e, EventState.NOT_SYNCED));
+ }
+ }
+
+ Enumeration ids = eventState.keys();
+ while (ids.hasMoreElements()) {
+ Long i = ids.nextElement();
+ EventSyncState es = eventState.get(i);
+ if (eventTable.containsKey(i)) {
+ if (es.getState() == EventState.SYNCED) {
+ if (!es.getEvent().equals(eventTable.get(i))) {
+ eventState.put(i, new EventSyncState(eventTable.get(i), EventState.NEEDS_UPDATE));
+ }
+ }
+ } else {
+ if (es.getState() == EventState.NOT_SYNCED) {
+ eventState.remove(i);
+ } else {
+ es.setState(EventState.NEEDS_DELETE);
+ eventState.put(i, es);
+ }
+ }
+ }
+
+ updateEvents();
+ }
+
+ private void updateEvents() {
+ Enumeration ids = eventState.keys();
+ while (ids.hasMoreElements()) {
+ Long i = ids.nextElement();
+ EventSyncState es = eventState.get(i);
+ if ((es.getState() == EventState.NOT_SYNCED) || (es.getState() == EventState.NEEDS_UPDATE)) {
+ CalendarEventSpec calendarEventSpec = new CalendarEventSpec();
+ calendarEventSpec.title = es.getEvent().getTitle();
+ calendarEventSpec.id = i;
+ calendarEventSpec.timestamp = es.getEvent().getBeginSeconds();
+ calendarEventSpec.description = es.getEvent().getDescription();
+ calendarEventSpec.type = CalendarEventSpec.TYPE_UNKNOWN;
+ GBApplication.deviceService().onDeleteCalendarEvent(CalendarEventSpec.TYPE_UNKNOWN, i);
+ GBApplication.deviceService().onAddCalendarEvent(calendarEventSpec);
+ es.setState(EventState.SYNCED);
+ eventState.put(i, es);
+ } else if (es.getState() == EventState.NEEDS_DELETE) {
+ GBApplication.deviceService().onDeleteCalendarEvent(CalendarEventSpec.TYPE_UNKNOWN, i);
+ eventState.remove(i);
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CalendarEvents.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CalendarEvents.java
index 63935aa4c..6918eae6b 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CalendarEvents.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/CalendarEvents.java
@@ -28,6 +28,7 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
+import java.util.Objects;
public class CalendarEvents {
@@ -155,5 +156,19 @@ public class CalendarEvents {
return calName;
}
+ @Override public boolean equals(Object other) {
+ if (other instanceof CalendarEvent) {
+ CalendarEvent e = (CalendarEvent) other;
+ return (this.getId() == e.getId()) &&
+ Objects.equals(this.getTitle(), e.getTitle()) &&
+ (this.getBegin() == e.getBegin()) &&
+ Objects.equals(this.getLocation(), e.getLocation()) &&
+ Objects.equals(this.getDescription(), e.getDescription()) &&
+ (this.getEnd() == e.getEnd()) &&
+ Objects.equals(this.getCalName(), e.getCalName());
+ } else {
+ return false;
+ }
+ }
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java
index 7fb8a4d68..9a3f7d637 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java
@@ -44,6 +44,7 @@ import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmClockReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.BluetoothConnectReceiver;
+import nodomain.freeyourgadget.gadgetbridge.externalevents.CalendarReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.MusicPlaybackReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.PebbleReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.PhoneCallReceiver;
@@ -167,6 +168,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
private AlarmClockReceiver mAlarmClockReceiver = null;
private AlarmReceiver mAlarmReceiver = null;
+ private CalendarReceiver mCalendarReceiver = null;
private Random mRandom = new Random();
private final String[] mMusicActions = {
@@ -613,6 +615,10 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
mAlarmReceiver = new AlarmReceiver();
registerReceiver(mAlarmReceiver, new IntentFilter("DAILY_ALARM"));
}
+ if (mCalendarReceiver == null) {
+ mCalendarReceiver = new CalendarReceiver();
+ registerReceiver(mCalendarReceiver, new IntentFilter("CALENDAR_SYNC"));
+ }
if (mAlarmClockReceiver == null) {
mAlarmClockReceiver = new AlarmClockReceiver();
IntentFilter filter = new IntentFilter();
@@ -649,6 +655,10 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
unregisterReceiver(mAlarmReceiver);
mAlarmReceiver = null;
}
+ if (mCalendarReceiver != null) {
+ unregisterReceiver(mCalendarReceiver);
+ mCalendarReceiver = null;
+ }
if (mAlarmClockReceiver != null) {
unregisterReceiver(mAlarmClockReceiver);
mAlarmClockReceiver = null;