diff --git a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/activity/AbstractBuddyActivity.java b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/activity/AbstractBuddyActivity.java index a90ee9f..f8d625a 100644 --- a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/activity/AbstractBuddyActivity.java +++ b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/activity/AbstractBuddyActivity.java @@ -1,6 +1,11 @@ package com.kunzisoft.remembirthday.activity; +import android.content.ContentProviderOperation; +import android.content.ContentProviderResult; +import android.content.OperationApplicationException; import android.os.Bundle; +import android.os.RemoteException; +import android.provider.CalendarContract; import android.support.v7.app.AppCompatActivity; import android.util.Log; @@ -12,6 +17,8 @@ import com.kunzisoft.remembirthday.provider.EventProvider; import com.kunzisoft.remembirthday.provider.UpdateBirthdayToContactTask; +import java.util.ArrayList; + /** * Abstract class to encapsulate the management of the birthday dialog. * @author joker on 06/07/17. @@ -110,20 +117,39 @@ public void onClickPositiveButton(DateUnknownYear dateUnknownYear) { updateBirthdayToContactTask.execute(); // Update event in calendar - // TODO UPDATE - /* - long calendarId = CalendarProvider.getCalendar(AbstractBuddyActivity.this); - if (calendarId != -1) { - EventProvider.insert(AbstractBuddyActivity.this, - calendarId, - CalendarEvent.buildCalendarEventFromContact( - AbstractBuddyActivity.this, - contact), - contact); + CalendarEvent event = EventProvider.getNextEventFromContact(AbstractBuddyActivity.this, contact); + if(event == null) { + long calendarId = CalendarProvider.getCalendar(AbstractBuddyActivity.this); + if (calendarId != -1) { + EventProvider.insert(AbstractBuddyActivity.this, + calendarId, + // TODO get reminders from list + CalendarEvent.buildCalendarEventFromContact( + AbstractBuddyActivity.this, + contact), + contact); + } else { + Log.e("CalendarSyncAdapter", "Unable to create calendar"); + } } else { - Log.e("CalendarSyncAdapter", "Unable to create calendar"); + event.setDateStart(DateUnknownYear.getNextAnniversary(dateUnknownYear)); + event.setAllDay(true); + Log.e(getClass().getSimpleName(), event.toString()); + ArrayList operations = new ArrayList<>(); + ContentProviderOperation contentProviderOperation = EventProvider.update(event); + operations.add(contentProviderOperation); + try { + ContentProviderResult[] contentProviderResults = + getContentResolver().applyBatch(CalendarContract.AUTHORITY, operations); + for(ContentProviderResult contentProviderResult : contentProviderResults) { + Log.d(getClass().getSimpleName(), contentProviderResult.toString()); + if (contentProviderResult.uri != null) + Log.d(getClass().getSimpleName(), contentProviderResult.uri.toString()); + } + } catch (RemoteException|OperationApplicationException e) { + Log.e(this.getClass().getSimpleName(), "Unable to update event : " + e.getMessage()); + } } - */ } @Override diff --git a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/activity/DetailsBuddyFragment.java b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/activity/DetailsBuddyFragment.java index 2b02b0e..376cb81 100644 --- a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/activity/DetailsBuddyFragment.java +++ b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/activity/DetailsBuddyFragment.java @@ -23,7 +23,8 @@ import com.kunzisoft.remembirthday.R; import com.kunzisoft.remembirthday.adapter.AutoMessageAdapter; import com.kunzisoft.remembirthday.adapter.MenuAdapter; -import com.kunzisoft.remembirthday.adapter.ReminderNotificationsAdapter; +import com.kunzisoft.remembirthday.adapter.ReminderCalendarObserver; +import com.kunzisoft.remembirthday.adapter.ReminderCalendarNotificationsAdapter; import com.kunzisoft.remembirthday.animation.AnimationCircle; import com.kunzisoft.remembirthday.element.CalendarEvent; import com.kunzisoft.remembirthday.element.Contact; @@ -71,7 +72,7 @@ public class DetailsBuddyFragment extends Fragment implements ActionContactMenu{ protected AutoMessageAdapter autoMessagesAdapter; protected RecyclerView remindersListView; - protected ReminderNotificationsAdapter remindersAdapter; + protected ReminderCalendarNotificationsAdapter remindersAdapter; private RecyclerView menuListView; private GridLayoutManager gridLayoutManager; @@ -181,7 +182,7 @@ public void onActivityCreated(Bundle savedInstanceState) { if(PreferencesManager.isCustomCalendarActive(getContext())) { // Add default reminders and link view to adapter - remindersAdapter = new ReminderNotificationsAdapter(getContext(), contact.getBirthday()); + remindersAdapter = new ReminderCalendarNotificationsAdapter(getContext(), contact.getBirthday()); remindersListView.setAdapter(remindersAdapter); // Build default elements @@ -191,6 +192,10 @@ public void onActivityCreated(Bundle savedInstanceState) { event.addReminders(reminders); Log.d(TAG, "Get event from calendar : " + event.toString()); remindersAdapter.addReminders(reminders); + + // Attach observer for changes + remindersAdapter.registerReminderObserver( + new ReminderCalendarObserver(getContext(), event)); } else { Log.e(TAG, "Error when get event from calendar"); } diff --git a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/AbstractReminderAdapter.java b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/AbstractReminderAdapter.java index e15e4cb..ca84804 100644 --- a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/AbstractReminderAdapter.java +++ b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/AbstractReminderAdapter.java @@ -31,10 +31,25 @@ public abstract class AbstractReminderAdapter> reminderDataObservers; + public AbstractReminderAdapter(Context context, DateUnknownYear anniversary) { this.context = context; this.anniversary = anniversary; - listReminders = new LinkedList<>(); + this.listReminders = new LinkedList<>(); + this.reminderDataObservers = new ArrayList<>(); + } + + public void registerReminderObserver(ReminderDataObserver reminderDataObserver) { + this.reminderDataObservers.add(reminderDataObserver); + } + + public void unregisterReminderObserver(ReminderDataObserver reminderDataObserver) { + this.reminderDataObservers.remove(reminderDataObserver); + } + + public void unregisterAllReminderObservers() { + this.reminderDataObservers.clear(); } /** @@ -46,6 +61,10 @@ public void addReminders(List reminders) { if(!reminders.isEmpty()) { listReminders.addAll(reminders); this.notifyItemRangeChanged(start, reminders.size() - 1); + // Notify all customs observers + for(ReminderDataObserver observer : reminderDataObservers) { + observer.onRemindersAdded(reminders); + } } } @@ -56,13 +75,12 @@ public void addReminders(List reminders) { public void addReminder(E reminder) { listReminders.add(reminder); this.notifyItemChanged(listReminders.size() - 1); + // Notify all customs observers + for(ReminderDataObserver observer : reminderDataObservers) { + observer.onReminderAdded(reminder); + } } - /** - * Add a default reminder to the list, init day with delta of anniversary, hour and minute to default - */ - public abstract void addDefaultItem(int deltaDay); - /** * Add a default reminder to the list with the day of anniversary, init hour and minute to default */ @@ -121,6 +139,10 @@ public void onClick(View view) { int position = listReminders.indexOf(reminder); notifyItemRemoved(position); listReminders.remove(position); + // Notify observable + for(ReminderDataObserver observer : reminderDataObservers) { + observer.onReminderDeleted(reminder); + } } } @@ -148,6 +170,11 @@ public void onTimeSet(TimePicker timePicker, int hourOfDay, int minute) { // Set text in view ((TextView) view).setText(reminderDateFormatter.format(reminder.getDate())); + + // Notify observable + for(ReminderDataObserver observer : reminderDataObservers) { + observer.onReminderUpdated(reminder); + } } }, reminder.getHourOfDay(), reminder.getMinuteOfHour(), true); timePickerDialog.show(); @@ -171,10 +198,30 @@ public OnDaySelected(E reminder, List listDays) { public void onItemSelected(AdapterView adapterView, View view, int position, long id) { // New Date when delta days is selected reminder.setDeltaDay(listDays.get(position)); + // Notify observable + for(ReminderDataObserver observer : reminderDataObservers) { + observer.onReminderUpdated(reminder); + } Log.d(this.getClass().getSimpleName(), "Assign new date for reminder : " + reminder.getDate().toString()); } @Override public void onNothingSelected(AdapterView adapterView) {} } + + /** + * Use to create observers of reminders + * @param Reminder type + */ + public interface ReminderDataObserver { + + void onReminderAdded(E reminder); + void onRemindersAdded(List reminders); + + void onReminderUpdated(E reminder); + void onRemindersUpdated(List reminders); + + void onReminderDeleted(E reminder); + void onRemindersDeleted(List reminders); + } } diff --git a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/AutoMessageAdapter.java b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/AutoMessageAdapter.java index aff73ce..140e457 100644 --- a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/AutoMessageAdapter.java +++ b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/AutoMessageAdapter.java @@ -20,15 +20,10 @@ public AutoMessageAdapter(Context context, DateUnknownYear anniversary) { super(context, anniversary); } - @Override - public void addDefaultItem(int deltaDay) { - int[] defaultTime = PreferencesManager.getDefaultTime(context); - addReminder(new AutoMessage(anniversary.getDate(), defaultTime[0], defaultTime[1], deltaDay)); - } - @Override public void addDefaultItem() { - addDefaultItem(0); + int[] defaultTime = PreferencesManager.getDefaultTime(context); + addReminder(new AutoMessage(anniversary.getDate(), defaultTime[0], defaultTime[1], 0)); } @Override diff --git a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/ReminderNotificationsAdapter.java b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/ReminderCalendarNotificationsAdapter.java similarity index 71% rename from RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/ReminderNotificationsAdapter.java rename to RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/ReminderCalendarNotificationsAdapter.java index 287eeda..85620ae 100644 --- a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/ReminderNotificationsAdapter.java +++ b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/ReminderCalendarNotificationsAdapter.java @@ -14,27 +14,22 @@ /** * Adapter who manage list of reminders */ -public class ReminderNotificationsAdapter extends AbstractReminderAdapter { +public class ReminderCalendarNotificationsAdapter extends AbstractReminderAdapter { - public ReminderNotificationsAdapter(Context context, DateUnknownYear anniversary) { + public ReminderCalendarNotificationsAdapter(Context context, DateUnknownYear anniversary) { super(context, anniversary); } - @Override - public void addDefaultItem(int deltaDay) { - int[] defaultTime = PreferencesManager.getDefaultTime(context); - addReminder(new Reminder(anniversary.getDate(), defaultTime[0], defaultTime[1], deltaDay)); - } - @Override public void addDefaultItem() { - addDefaultItem(0); + int[] defaultTime = PreferencesManager.getDefaultTime(context); + addReminder(new Reminder(anniversary.getDate(), defaultTime[0], defaultTime[1], 0)); } @Override public ReminderViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_list_reminder_notifs, parent, false); - return new AutoMessageViewHolder(itemView); + return new ReminderViewHolder(itemView); } } diff --git a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/ReminderCalendarObserver.java b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/ReminderCalendarObserver.java new file mode 100644 index 0000000..7817aa9 --- /dev/null +++ b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/ReminderCalendarObserver.java @@ -0,0 +1,97 @@ +package com.kunzisoft.remembirthday.adapter; + +import android.content.ContentProviderOperation; +import android.content.ContentProviderResult; +import android.content.ContentResolver; +import android.content.Context; +import android.content.OperationApplicationException; +import android.os.RemoteException; +import android.provider.CalendarContract; +import android.util.Log; + +import com.kunzisoft.remembirthday.element.CalendarEvent; +import com.kunzisoft.remembirthday.element.Reminder; +import com.kunzisoft.remembirthday.provider.ReminderProvider; + +import java.util.ArrayList; +import java.util.List; + +/** + * Observer who do actions for reminders + * Created by joker on 04/08/17. + */ +public class ReminderCalendarObserver implements AbstractReminderAdapter.ReminderDataObserver { + + private Context context; + private CalendarEvent event; + private ContentResolver contentResolver; + private ArrayList ops; + + public ReminderCalendarObserver(Context context, CalendarEvent calendarEvent) { + this.context = context; + this.event = calendarEvent; + this.contentResolver = context.getContentResolver(); + this.ops = new ArrayList<>(); + } + + @Override + public void onReminderAdded(Reminder reminder) { + ops.add(ReminderProvider.insert(context, event.getId(), reminder)); + //TODO Add id to reminder + applyBatch(); + } + + @Override + public void onRemindersAdded(List reminders) { + //TODO Add id to reminder + for(Reminder reminder : reminders) { + ops.add(ReminderProvider.insert(context, event.getId(), reminder)); + } + applyBatch(); + } + + @Override + public void onReminderUpdated(Reminder reminder) { + ops.add(ReminderProvider.update(context, event.getId(), reminder)); + applyBatch(); + } + + @Override + public void onRemindersUpdated(List reminders) { + for(Reminder reminder : reminders) { + ops.add(ReminderProvider.update(context, event.getId(), reminder)); + } + applyBatch(); + } + + @Override + public void onReminderDeleted(Reminder reminder) { + ops.add(ReminderProvider.delete(context, event.getId(), reminder)); + applyBatch(); + } + + @Override + public void onRemindersDeleted(List reminders) { + for(Reminder reminder : reminders) { + ops.add(ReminderProvider.delete(context, event.getId(), reminder)); + } + applyBatch(); + } + + /** + * Apply operations + */ + private void applyBatch() { + try { + ContentProviderResult[] contentProviderResults = + contentResolver.applyBatch(CalendarContract.AUTHORITY, ops); + for(ContentProviderResult result : contentProviderResults) + if(result.uri != null) + Log.d(this.getClass().getSimpleName(), result.uri.toString()); + } catch (RemoteException|OperationApplicationException e) { + Log.e(this.getClass().getSimpleName(), e.getMessage()); + } finally { + ops.clear(); + } + } +} diff --git a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/ReminderDataObserver.java b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/ReminderDataObserver.java deleted file mode 100644 index 68511bb..0000000 --- a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/adapter/ReminderDataObserver.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.kunzisoft.remembirthday.adapter; - -import android.content.Context; -import android.support.v7.widget.RecyclerView; - -import com.kunzisoft.remembirthday.element.CalendarEvent; - -/** - * Created by joker on 02/08/17. - */ -public class ReminderDataObserver extends RecyclerView.AdapterDataObserver { - - // TODO reminders - - private Context context; - private CalendarEvent calendarEvent; - - public ReminderDataObserver(Context context, CalendarEvent event) { - this.context = context; - this.calendarEvent = event; - } - - @Override - public void onChanged() { - super.onChanged(); - - } -} diff --git a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/element/DateUnknownYear.java b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/element/DateUnknownYear.java index 3e6f0dd..04db722 100644 --- a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/element/DateUnknownYear.java +++ b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/element/DateUnknownYear.java @@ -141,6 +141,24 @@ public boolean nextAnniversaryIsToday() { */ // TODO TEST public Date getNextAnniversary() { + return getNextAnniversary(this.date); + } + + /** + * Gets the anniversary date not yet passed + * @param date Date without year + * @return Next anniversary in the year + */ + public static Date getNextAnniversary(DateUnknownYear date) { + return getNextAnniversary(date.getDate()); + } + + /** + * Gets the anniversary date not yet passed + * @param date Date + * @return Next anniversary in the year + */ + public static Date getNextAnniversary(Date date) { DateTime dateTimeNow = DateTime.now(); MonthDay monthDayNow = MonthDay.now(); MonthDay monthDayOfNextDate = MonthDay.fromDateFields(date); @@ -154,6 +172,7 @@ public Date getNextAnniversary() { } } + /** * Number of years between a date and today * @param date Date: Year for calculate number diff --git a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/provider/EventProvider.java b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/provider/EventProvider.java index 6136dba..b0e9938 100644 --- a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/provider/EventProvider.java +++ b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/provider/EventProvider.java @@ -35,7 +35,6 @@ public class EventProvider { * @param event Event to add */ private static void assignValuesInBuilder(ContentProviderOperation.Builder builder, CalendarEvent event) { - if(event.isAllDay()) { // ALL_DAY events must be UTC DateTime dateTimeStartUTC = new DateTime(event.getDateStart()).withZoneRetainFields(DateTimeZone.UTC); @@ -98,7 +97,6 @@ public static ContentProviderOperation insert(Context context, long calendarId, * @return ContentProviderOperation to apply or null if no id */ public static ContentProviderOperation update(CalendarEvent event) { - if(event.hasId()) { ContentProviderOperation.Builder builder; builder = ContentProviderOperation.newUpdate( diff --git a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/provider/ReminderProvider.java b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/provider/ReminderProvider.java index 1297b68..10d6260 100644 --- a/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/provider/ReminderProvider.java +++ b/RememBirthday-UI/src/main/java/com/kunzisoft/remembirthday/provider/ReminderProvider.java @@ -22,8 +22,8 @@ public class ReminderProvider { public static List getRemindersFromEvent(Context context, CalendarEvent calendarEvent) { List reminderList = new ArrayList<>(); - String[] projection = new String[] { + CalendarContract.Reminders._ID, CalendarContract.Reminders.EVENT_ID, CalendarContract.Reminders.MINUTES, CalendarContract.Reminders.METHOD}; @@ -43,6 +43,7 @@ public static List getRemindersFromEvent(Context context, CalendarEven Reminder reminder = new Reminder( calendarEvent.getDate(), cursor.getInt(cursor.getColumnIndex(CalendarContract.Reminders.MINUTES))); + reminder.setId(cursor.getLong(cursor.getColumnIndex(CalendarContract.Reminders._ID))); reminderList.add(reminder); cursor.moveToNext(); } @@ -51,31 +52,50 @@ public static List getRemindersFromEvent(Context context, CalendarEven return reminderList; } - // TODO mutualize public static ContentProviderOperation insert(Context context, long eventId, Reminder reminder) { - ContentProviderOperation.Builder builder = ContentProviderOperation .newInsert(CalendarProvider.getBirthdayAdapterUri(context, CalendarContract.Reminders.CONTENT_URI)); - builder.withValue(CalendarContract.Reminders.EVENT_ID, eventId); - builder.withValue(CalendarContract.Reminders.MINUTES, reminder.getMinutesBeforeEvent()); - builder.withValue(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT); - return builder.build(); + return insert(builder, reminder); } public static ContentProviderOperation insert(Context context, Reminder reminder, int backref) { ContentProviderOperation.Builder builder = ContentProviderOperation .newInsert(CalendarProvider.getBirthdayAdapterUri(context, CalendarContract.Reminders.CONTENT_URI)); - /* * add reminder to last added event identified by backRef * see http://stackoverflow.com/questions/4655291/semantics-of- * withvaluebackreference */ builder.withValueBackReference(CalendarContract.Reminders.EVENT_ID, backref); + return insert(builder, reminder); + } + + private static ContentProviderOperation insert(ContentProviderOperation.Builder builder, Reminder reminder) { builder.withValue(CalendarContract.Reminders.MINUTES, reminder.getMinutesBeforeEvent()); builder.withValue(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT); return builder.build(); } + + public static ContentProviderOperation update(Context context, long eventId, Reminder reminder) { + ContentProviderOperation.Builder builder = ContentProviderOperation + .newUpdate(CalendarProvider.getBirthdayAdapterUri(context, CalendarContract.Reminders.CONTENT_URI)) + .withSelection(CalendarContract.Reminders._ID + " =?" + + " AND " + CalendarContract.Reminders.EVENT_ID + " =?" + , new String[]{String.valueOf(reminder.getId()), + String.valueOf(eventId)}) + .withValue(CalendarContract.Reminders.MINUTES, reminder.getMinutesBeforeEvent()); + return builder.build(); + } + + public static ContentProviderOperation delete(Context context, long eventId, Reminder reminder) { + ContentProviderOperation.Builder builder = ContentProviderOperation + .newDelete(CalendarProvider.getBirthdayAdapterUri(context, CalendarContract.Reminders.CONTENT_URI)) + .withSelection(CalendarContract.Reminders._ID + " =?" + + " AND " + CalendarContract.Reminders.EVENT_ID + " =?" + , new String[]{String.valueOf(reminder.getId()), + String.valueOf(eventId)}); + return builder.build(); + } }