3

I have a list of events in my app. A button on the side lets the user add the event date and time to his/her calender. I use a calender intent to redirect the user to the android calender which the corresponding date and time. Now after the user adds the event to his calender, I would like to disable the 'add event' button which corresponds to the events he/she had already added(so the user avoid adding the same event again). How can I do this? I have gone through the new calender API for android 4.0 but I wasnt able to achieve what I wanted.

Basically what I want is to avoid repeated entries for the same event in the users calender.

Any help would be appreciated.

Rudi Visser
  • 21,350
  • 5
  • 71
  • 97
TMS
  • 1,201
  • 1
  • 13
  • 20

4 Answers4

7

You should test, if an instance for this event exists. See the documentation of the Android's CalendarContract.Instances class.

Especially the second query method should be helpful in this case.

This examples is some code, I posted on my blog post about the CalendarContract provider - slightly altered for your needs:

long begin = // starting time in milliseconds
long end = // ending time in milliseconds
String[] proj = 
      new String[]{
            Instances._ID, 
            Instances.BEGIN, 
            Instances.END, 
            Instances.EVENT_ID};
Cursor cursor = 
      Instances.query(getContentResolver(), proj, begin, end, "\"Your event title\"");
if (cursor.getCount() > 0) {
   // deal with conflict
}

Be aware: The time is always in UTC millis since the epoch. So you might have to adjust given the user's timezone.

And the last parameter should contain the title of the event you have added to the calendar. Keep the quotes - otherwise Android looks for "your" or "event" or "title"!

And do not forget to include the necessary permissions.

Wolfram Rittmeyer
  • 2,402
  • 1
  • 18
  • 21
  • Thank you very much. Just the thing I am looking for. However.. the query returns 0 if I include the event title. The first query in the documentation(without the search term) works perfectly. Can you help me out? – TMS Nov 20 '12 at 12:51
  • I ended up using the first query to retrieve all the events between start time and end time, and comparing the event titles using an if condition. – TMS Nov 21 '12 at 04:14
  • Sorry, I had no time to look into this. But I still will have a look at it, because now I'm interested on why the second one doesn't work. – Wolfram Rittmeyer Nov 21 '12 at 09:56
  • Please check this, this might help: private static boolean isEventInCalendar(Context context, String titleText, long dtStart, long dtEnd) { final String[] projection = new String[]{CalendarContract.Instances.BEGIN, CalendarContract.Instances.END, CalendarContract.Instances.TITLE}; Cursor cursor = CalendarContract.Instances.query(context.getContentResolver(), projection, dtStart, dtEnd); return cursor != null && cursor.moveToFirst() && cursor.getString(cursor.getColumnIndex(CalendarContract.Instances.TITLE)).equalsIgnoreCase(titleText); } – van17 Jul 03 '18 at 22:25
  • it is giving false everytime, can you plese explain how it will work? – Dolly Rosy Mar 16 '19 at 04:12
1

Instances.query is not recommended to be run on the UI thread, but can be done efficiently by ensuring start and end time duration is minimized.

The search string will search all values, not just title, so adding a loop to check for that an exact field value is necessary.

public boolean eventExistsOnCalendar(String eventTitle, long startTimeMs, long endTimeMs) {
  if (eventTitle == null || "".equals(eventTitle)) {
    return false;
  }
  if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
    return false;
  }
  // If no end time, use start + 1 hour or = 1 day. Query is slow if searching a huge time range
  if (endTimeMs <= 0) {
    endTimeMs = startTimeMs + 1000 * 60 * 60; // + 1 hour
  }

  final ContentResolver resolver = mContext.getContentResolver();
  final String[] duplicateProjection = {CalendarContract.Events.TITLE}; // Can change to whatever unique param you are searching for
  Cursor cursor =
      CalendarContract.Instances.query(
          resolver,
          duplicateProjection,
          startTimeMs,
          endTimeMs,
          '"' + eventTitle + '"');

  if (cursor == null) {
    return false;
  }
  if (cursor.getCount() == 0) {
    cursor.close();
    return false;
  }

  while (cursor.moveToNext()) {
    String title = cursor.getString(0);
    if (eventTitle.equals(title)) {
      cursor.close();
      return true;
    }
  }

  cursor.close();
  return false;
}
Gibolt
  • 42,564
  • 15
  • 187
  • 127
0

I have used following way to check it ...what i am passing event_id to check whether is it in calendar or not....

public boolean isEventInCal(Context context, String cal_meeting_id) {

     Cursor cursor = context.getContentResolver().query(
     Uri.parse("content://com.android.calendar/events"),
       new String[] { "_id" }, " _id = ? ",
       new String[] { cal_meeting_id }, null);

           if (cursor.moveToFirst()) {
                   //Yes Event Exist...
      return true;
     }
     return false;
    }
Dhruvit Darji
  • 205
  • 2
  • 14
0

Please check this, this might help:

private static boolean isEventInCalendar(Context context, String titleText, long dtStart, long dtEnd) {

    final String[] projection = new String[]{CalendarContract.Instances.BEGIN, CalendarContract.Instances.END, CalendarContract.Instances.TITLE};
    Cursor cursor = CalendarContract.Instances.query(context.getContentResolver(), projection, dtStart, dtEnd);
    return cursor != null && cursor.moveToFirst() && cursor.getString(cursor.getColumnIndex(CalendarContract.Instances.TITLE)).equalsIgnoreCase(titleText);
}
van17
  • 171
  • 1
  • 9