Add CalendarEventProvider

pull/384/head
Alex Baker 9 years ago
parent 4bc6260d11
commit e97fb0b8cf

@ -14,6 +14,8 @@ import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.utility.Constants;
import org.tasks.R;
import org.tasks.calendars.AndroidCalendarEvent;
import org.tasks.calendars.CalendarEventProvider;
import org.tasks.injection.InjectingBroadcastReceiver;
import org.tasks.preferences.PermissionChecker;
import org.tasks.preferences.Preferences;
@ -27,19 +29,11 @@ import javax.inject.Inject;
import timber.log.Timber;
import static android.provider.BaseColumns._ID;
public class CalendarAlarmReceiver extends InjectingBroadcastReceiver {
public static final int REQUEST_CODE_CAL_REMINDER = 100;
public static final String BROADCAST_CALENDAR_REMINDER = Constants.PACKAGE + ".CALENDAR_EVENT";
private static final String[] EVENTS_PROJECTION = {
CalendarContract.Events.DTSTART,
CalendarContract.Events.DTEND,
CalendarContract.Events.TITLE,
};
private static final String[] ATTENDEES_PROJECTION = {
CalendarContract.Attendees.ATTENDEE_NAME,
CalendarContract.Attendees.ATTENDEE_EMAIL,
@ -47,6 +41,7 @@ public class CalendarAlarmReceiver extends InjectingBroadcastReceiver {
@Inject Preferences preferences;
@Inject PermissionChecker permissionChecker;
@Inject CalendarEventProvider calendarEventProvider;
@Override
public void onReceive(Context context, Intent intent) {
@ -85,88 +80,72 @@ public class CalendarAlarmReceiver extends InjectingBroadcastReceiver {
}
private void showCalReminder(Context context, long eventId, boolean fromPostpone) {
AndroidCalendarEvent event = calendarEventProvider.getEvent(eventId);
if (event == null) {
return;
}
ContentResolver cr = context.getContentResolver();
String[] eventArg = new String[]{Long.toString(eventId)};
boolean shouldShowReminder;
if (fromPostpone) {
long timeAfter = DateUtilities.now() - event.getEnd();
shouldShowReminder = (timeAfter > DateUtilities.ONE_MINUTE * 2);
} else {
long timeUntil = event.getStart() - DateUtilities.now();
shouldShowReminder = (timeUntil > 0 && timeUntil < DateUtilities.ONE_MINUTE * 20);
}
String[] eventArg = new String[] { Long.toString(eventId) };
Cursor event = cr.query(CalendarContract.Events.CONTENT_URI,
EVENTS_PROJECTION,
_ID + " = ?",
eventArg,
null);
try {
if (event.moveToFirst()) {
int dtstartIndex = event.getColumnIndexOrThrow(CalendarContract.Events.DTSTART);
int dtendIndex = event.getColumnIndexOrThrow(CalendarContract.Events.DTEND);
int titleIndex = event.getColumnIndexOrThrow(CalendarContract.Events.TITLE);
String title = event.getString(titleIndex);
long startTime = event.getLong(dtstartIndex);
long endTime = event.getLong(dtendIndex);
boolean shouldShowReminder;
if (fromPostpone) {
long timeAfter = DateUtilities.now() - endTime;
shouldShowReminder = (timeAfter > DateUtilities.ONE_MINUTE * 2);
} else {
long timeUntil = startTime - DateUtilities.now();
shouldShowReminder = (timeUntil > 0 && timeUntil < DateUtilities.ONE_MINUTE * 20);
if (shouldShowReminder) {
// Get attendees
Cursor attendees = cr.query(CalendarContract.Attendees.CONTENT_URI,
ATTENDEES_PROJECTION,
CalendarContract.Attendees.EVENT_ID + " = ? ",
eventArg,
null);
try {
// Do something with attendees
int emailIndex = attendees.getColumnIndexOrThrow(CalendarContract.Attendees.ATTENDEE_EMAIL);
int nameIndex = attendees.getColumnIndexOrThrow(CalendarContract.Attendees.ATTENDEE_NAME);
ArrayList<String> names = new ArrayList<>();
ArrayList<String> emails = new ArrayList<>();
Account[] accountArray = AccountManager.get(context).getAccounts();
Set<String> phoneAccounts = new HashSet<>();
for (Account a : accountArray) {
phoneAccounts.add(a.name);
}
if (shouldShowReminder) {
// Get attendees
Cursor attendees = cr.query(CalendarContract.Attendees.CONTENT_URI,
ATTENDEES_PROJECTION,
CalendarContract.Attendees.EVENT_ID + " = ? ",
eventArg,
null);
try {
// Do something with attendees
int emailIndex = attendees.getColumnIndexOrThrow(CalendarContract.Attendees.ATTENDEE_EMAIL);
int nameIndex = attendees.getColumnIndexOrThrow(CalendarContract.Attendees.ATTENDEE_NAME);
ArrayList<String> names = new ArrayList<>();
ArrayList<String> emails = new ArrayList<>();
Account[] accountArray = AccountManager.get(context).getAccounts();
Set<String> phoneAccounts = new HashSet<>();
for (Account a : accountArray) {
phoneAccounts.add(a.name);
boolean includesMe = false;
for (attendees.moveToFirst(); !attendees.isAfterLast(); attendees.moveToNext()) {
String name = attendees.getString(nameIndex);
String email = attendees.getString(emailIndex);
if (!TextUtils.isEmpty(email)) {
if (phoneAccounts.contains(email)) {
includesMe = true;
continue;
}
boolean includesMe = false;
for (attendees.moveToFirst(); !attendees.isAfterLast(); attendees.moveToNext()) {
String name = attendees.getString(nameIndex);
String email = attendees.getString(emailIndex);
if (!TextUtils.isEmpty(email)) {
if (phoneAccounts.contains(email)) {
includesMe = true;
continue;
}
names.add(name);
emails.add(email);
}
}
if (emails.size() > 0 && includesMe) {
Intent reminderActivity = new Intent(context, CalendarReminderActivity.class);
reminderActivity.putStringArrayListExtra(CalendarReminderActivity.TOKEN_NAMES, names);
reminderActivity.putStringArrayListExtra(CalendarReminderActivity.TOKEN_EMAILS, emails);
reminderActivity.putExtra(CalendarReminderActivity.TOKEN_EVENT_ID, eventId);
reminderActivity.putExtra(CalendarReminderActivity.TOKEN_EVENT_NAME, title);
reminderActivity.putExtra(CalendarReminderActivity.TOKEN_EVENT_START_TIME, startTime);
reminderActivity.putExtra(CalendarReminderActivity.TOKEN_EVENT_END_TIME, endTime);
reminderActivity.putExtra(CalendarReminderActivity.TOKEN_FROM_POSTPONE, fromPostpone);
reminderActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
context.startActivity(reminderActivity);
}
} finally {
attendees.close();
names.add(name);
emails.add(email);
}
}
if (emails.size() > 0 && includesMe) {
Intent reminderActivity = new Intent(context, CalendarReminderActivity.class);
reminderActivity.putStringArrayListExtra(CalendarReminderActivity.TOKEN_NAMES, names);
reminderActivity.putStringArrayListExtra(CalendarReminderActivity.TOKEN_EMAILS, emails);
reminderActivity.putExtra(CalendarReminderActivity.TOKEN_EVENT_ID, eventId);
reminderActivity.putExtra(CalendarReminderActivity.TOKEN_EVENT_NAME, event.getTitle());
reminderActivity.putExtra(CalendarReminderActivity.TOKEN_EVENT_START_TIME, event.getStart());
reminderActivity.putExtra(CalendarReminderActivity.TOKEN_EVENT_END_TIME, event.getEnd());
reminderActivity.putExtra(CalendarReminderActivity.TOKEN_FROM_POSTPONE, fromPostpone);
reminderActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
context.startActivity(reminderActivity);
}
} finally {
attendees.close();
}
} finally {
event.close();
}
}
}

@ -0,0 +1,42 @@
package org.tasks.calendars;
public class AndroidCalendarEvent {
private long id;
private final String title;
private final long start;
private final long end;
public AndroidCalendarEvent(long id, String title, long start, long end) {
this.id = id;
this.title = title;
this.start = start;
this.end = end;
}
public long getId() {
return id;
}
public String getTitle() {
return title;
}
public long getStart() {
return start;
}
public long getEnd() {
return end;
}
@Override
public String toString() {
return "AndroidCalendarEvent{" +
"id=" + id +
", title='" + title + '\'' +
", start=" + start +
", end=" + end +
'}';
}
}

@ -0,0 +1,86 @@
package org.tasks.calendars;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CalendarContract;
import android.support.annotation.Nullable;
import org.tasks.injection.ForApplication;
import org.tasks.preferences.PermissionChecker;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
import timber.log.Timber;
import static android.provider.BaseColumns._ID;
public class CalendarEventProvider {
private static final String[] COLUMNS = {
_ID,
CalendarContract.Events.DTSTART,
CalendarContract.Events.DTEND,
CalendarContract.Events.TITLE
};
private final ContentResolver contentResolver;
private final PermissionChecker permissionChecker;
@Inject
public CalendarEventProvider(@ForApplication Context context, PermissionChecker permissionChecker) {
this.permissionChecker = permissionChecker;
contentResolver = context.getContentResolver();
}
@Nullable
public AndroidCalendarEvent getEvent(long eventId) {
List<AndroidCalendarEvent> events = getCalendarEvents(CalendarContract.Events.CONTENT_URI,
_ID + " = ?", new String[] { Long.toString(eventId) });
return events.isEmpty() ? null : events.get(0);
}
public List<AndroidCalendarEvent> getEventsBetween(long start, long end) {
return getCalendarEvents(
CalendarContract.Events.CONTENT_URI,
CalendarContract.Events.DTSTART + " > ? AND " + CalendarContract.Events.DTSTART + " < ?",
new String[] { Long.toString(start), Long.toString(end) });
}
private List<AndroidCalendarEvent> getCalendarEvents(Uri uri, String selection, String[] selectionArgs) {
if (!permissionChecker.canAccessCalendars()) {
return Collections.emptyList();
}
List<AndroidCalendarEvent> events = new ArrayList<>();
Cursor cursor = null;
try {
cursor = contentResolver.query(uri, COLUMNS, selection, selectionArgs, null);
if (cursor != null && cursor.getCount() > 0) {
int idIndex = cursor.getColumnIndex(_ID);
int startIndex = cursor.getColumnIndexOrThrow(CalendarContract.Events.DTSTART);
int endIndex = cursor.getColumnIndexOrThrow(CalendarContract.Events.DTEND);
int titleIndex = cursor.getColumnIndexOrThrow(CalendarContract.Events.TITLE);
while (cursor.moveToNext()) {
events.add(new AndroidCalendarEvent(
cursor.getLong(idIndex),
cursor.getString(titleIndex),
cursor.getLong(startIndex),
cursor.getLong(endIndex)));
}
}
} catch (Exception e) {
Timber.e(e, e.getMessage());
} finally {
if (cursor != null) {
cursor.close();
}
}
return events;
}
}

@ -1,34 +1,34 @@
package org.tasks.scheduling;
import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CalendarContract;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.gcal.CalendarAlarmReceiver;
import org.tasks.R;
import org.tasks.calendars.AndroidCalendarEvent;
import org.tasks.calendars.CalendarEventProvider;
import org.tasks.injection.ForApplication;
import org.tasks.preferences.PermissionChecker;
import org.tasks.preferences.Preferences;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import static android.provider.BaseColumns._ID;
import timber.log.Timber;
public class CalendarNotificationIntentService extends RecurringIntervalIntentService {
private static final long FIFTEEN_MINUTES = TimeUnit.MINUTES.toMillis(15);
public static final String URI_PREFIX = "cal-reminder";
public static final String URI_PREFIX_POSTPONE = "cal-postpone";
@Inject Preferences preferences;
@Inject PermissionChecker permissionChecker;
@Inject CalendarEventProvider calendarEventProvider;
@Inject @ForApplication Context context;
@Inject AlarmManager alarmManager;
@ -38,50 +38,27 @@ public class CalendarNotificationIntentService extends RecurringIntervalIntentSe
@Override
void run() {
ContentResolver cr = context.getContentResolver();
long now = DateUtilities.now();
long start = now + FIFTEEN_MINUTES;
long end = now + TimeUnit.DAYS.toMillis(1);
for (final AndroidCalendarEvent event : calendarEventProvider.getEventsBetween(start, end)) {
Timber.d("Scheduling reminder for %s", event);
Intent eventAlarm = new Intent(context, CalendarAlarmReceiver.class) {{
setAction(CalendarAlarmReceiver.BROADCAST_CALENDAR_REMINDER);
setData(Uri.parse(URI_PREFIX + "://" + event.getId()));
}};
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
CalendarAlarmReceiver.REQUEST_CODE_CAL_REMINDER, eventAlarm, PendingIntent.FLAG_CANCEL_CURRENT);
Cursor events = cr.query(CalendarContract.Events.CONTENT_URI,
new String[] {_ID, CalendarContract.Events.DTSTART},
CalendarContract.Events.DTSTART + " > ? AND " + CalendarContract.Events.DTSTART + " < ?",
new String[] { Long.toString(now + DateUtilities.ONE_MINUTE * 15), Long.toString(now + DateUtilities.ONE_DAY) },
null);
try {
if (events != null && events.getCount() > 0) {
int idIndex = events.getColumnIndex(_ID);
int dtstartIndex = events.getColumnIndexOrThrow(CalendarContract.Events.DTSTART);
for (events.moveToFirst(); !events.isAfterLast(); events.moveToNext()) {
Intent eventAlarm = new Intent(context, CalendarAlarmReceiver.class);
eventAlarm.setAction(CalendarAlarmReceiver.BROADCAST_CALENDAR_REMINDER);
long start = events.getLong(dtstartIndex);
long id = events.getLong(idIndex);
eventAlarm.setData(Uri.parse(URI_PREFIX + "://" + id));
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
CalendarAlarmReceiver.REQUEST_CODE_CAL_REMINDER, eventAlarm, 0);
alarmManager.cancel(pendingIntent);
long alarmTime = start - DateUtilities.ONE_MINUTE * 15;
alarmManager.wakeup(alarmTime, pendingIntent);
}
}
} finally {
if (events != null) {
events.close();
}
alarmManager.wakeup(event.getStart() - FIFTEEN_MINUTES, pendingIntent);
}
}
@Override
long intervalMillis() {
return preferences.getBoolean(R.string.p_calendar_reminders, false) && permissionChecker.canAccessCalendars()
? TimeUnit.HOURS.toMillis(12)
: 0;
return preferences.getBoolean(R.string.p_calendar_reminders, false) ? TimeUnit.HOURS.toMillis(12) : 0;
}
@Override

Loading…
Cancel
Save