27

I am trying to make my App add reminders to the user's Calendar. The code searches for the title and start date to check if the event already exists in the Calendar before adding it (so as not to have duplicates). My problem is that: if I remove the event from the Calendar manually (using the Calendar), the event disappears from the Calendar (I am viewing all my Calendars and can't see it in the Calendar Application) but not from the DataBase. Another thing I don't understand is that I tried to remove the events programmatically, but still they are not removed.

Here is my code snippet:

Cursor cur = null;
ContentResolver cr = getContentResolver();
String calUriString = "content://com.android.calendar/events";
Uri cal=Uri.parse(calUriString);
String[] EVENT_PROJECTION=new String[]{"calendar_id","title","dtstart","_id"};
String selection = "((" + "calendar_id" + " = 1) AND ("
        + "title" + " LIKE '"+name+"') AND ("
        + "dtstart" + " = "+String.valueOf(c.getTimeInMillis())+"))";

cur = cr.query(cal, EVENT_PROJECTION, selection, null, null);

boolean found=false;
if(cur!=null) 
    if(cur.moveToFirst()){
        DatabaseUtils.dumpCursor(cur);/*Just to view my results (which always include the deleted events)*/
        do{
            if(cur.getString(1).equals(name)){
                /*I use this part to try to remove the events manually*/
                Uri eventUri =ContentUris.withAppendedId(cal, Long.valueOf(cur.getString(3)));
                String reminderUriString = "content://com.android.calendar/reminders";
                Uri remUri =Uri.parse(reminderUriString);
                cr.delete(remUri, "event_id="+cur.getString(3), null);
                cr.delete(eventUri, null, null);
                /*It is not working also*/

                Toast.makeText(getApplicationContext(), "Event already exists in Calendar", Toast.LENGTH_LONG).show();
                found=true;
                //break;
            }
        }while(cur.moveToNext());
    }
    cur.close();
    if(found){
        /*Event is found even if I remove it from the Calendar manually and even if I remove it programmatically using cr.delete()*/
    }
    else{
        values.put("calendar_id",1); /*I am using the same Calendar that I query, or is this wrong*/
        values.put("title", name);
        /*More values are added*/
        Uri calendarUri = cr.insert(cal, values);
        long eventID = Long.parseLong(calendarUri.getLastPathSegment());
        String reminderUriString = "content://com.android.calendar/reminders";
        ContentValues reminderValues = new ContentValues();
        reminderValues.put("event_id", eventID);
        reminderValues.put("minutes", 5); 
        reminderValues.put("method", 1); 
        Uri reminderUri = getApplicationContext().getContentResolver().insert(Uri.parse(reminderUriString),  reminderValues);
    }

Why are the events still present after removing them from the calendar Application and why am I not able to remove it even programmatically?

Update The problem is only if I use calendar_id=1 for inserting and deleting. Other calendar_ids work fine.

Update 2 I tested the code on Samsung Galaxy S1 and it is working fine. It seems to be a problem in Samsung Galaxy S3 (where I have my problem, I think it is a bug in the S-planner App)

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
Mohamed_AbdAllah
  • 5,311
  • 3
  • 28
  • 47

3 Answers3

18

If its not a URI problem,

Can you try to include in the selection string

AND (deleted != 1)

so the selection string becomes,

String selection = "((" + "calendar_id" + " = 1) AND ("
    + "title" + " LIKE '"+name+"') AND ("
    + "dtstart" + " = "+String.valueOf(c.getTimeInMillis())+") AND ( deleted != 1 ) )";

Occasionally, the CalendarDB takes sometime for the events to be removed. But the 'deleted' COLUMN will be marked as '1' indicating that they will be deleted soon. The reason for the delay maybe the calendar is waiting to be synced

p.s: Try using this tool -- http://www.cellobject.net/Tools/CellObjectSQLiteXMLBrowser.aspx to visualize the Calendar DB. Please check for the 'deleted' and 'dirty' columns in the db

A machan
  • 809
  • 1
  • 6
  • 6
  • 1
    There is still a bug in the S-planner App on Galaxy S3 as the deleted events never gets deleted with time as you mentioned. Your code works in filtering the deleted events from the query result, but I switched my phone On & Off and waited a lot of time and the events are still in the ContentProvider DB (although with the column deleted = 1) and never removed. – Mohamed_AbdAllah Apr 14 '13 at 20:57
  • Is there any syncing involved in the for the Calendar in which the event is deleted (like Exchange account or Google account). If so then, it will take some time to be synced and deleted. – A machan Apr 16 '13 at 20:17
  • 1
    I have been facing this issue since two months now and the data I added two months ago is still present (with deleted state). I don't think it is a time issue. – Mohamed_AbdAllah Apr 16 '13 at 22:25
  • I have been syncing the Calendar using Exchange account, so I see delays in getting the events removed. When the calendar syncs with the server, I see that the events are no longer present in it. – A machan Apr 17 '13 at 12:39
  • 1
    As a side note, you can use constants like `CalendarContract.Events.DELETED` for your selection string. – sulai Aug 29 '13 at 10:42
  • @Mohamed_AbdAllah were you ever able to delete calendar events from a Samsung? – Kaloyan Roussev Jan 04 '16 at 18:41
  • @Amachan, you saved my day. Thanks – Hiren Patel Sep 07 '16 at 04:53
1

Different versions of android use different URI paths for looking up calendar data. For example, you could use the following constants for android 2.1 and 2.2:

private static final String URI_VERSION_2_1 = "content://calendar/events";
private static final String URI_VERSION_2_2 = "content://com.android.calendar/events";

In 4.0 an different method is preferred:

http://android-developers.blogspot.com/2011/10/ics-and-non-public-apis.html http://developer.android.com/reference/android/provider/CalendarContract.Events.html

There is a good chance that the Galaxy S3 has at least Android 4.0 on it. This change may account for the code working on an S1, but not an S3.

Shellum
  • 3,159
  • 2
  • 21
  • 26
  • 1
    This is not a URI problem. I already find the data using the a/m URI and it is still visible in the Cursor if deleted from S-Planner. I tried changing the URI, but I get the same output. – Mohamed_AbdAllah Mar 19 '13 at 11:12
  • Okay. I guess one of my points is that if you're not >= 4.0 and not using the new APIs, that Google says good luck, your code will probably break at some point. I know that doesn't help you too much, but that's their official statement. – Shellum Mar 19 '13 at 15:29
  • 1
    Thank you for your support, but I actually tried almost everything, including specifying the URI per SDK. – Mohamed_AbdAllah Mar 19 '13 at 17:15
0

You can also do something like this:

private boolean isEventInCal(Context context, String id) {
    Uri event = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, Long.parseLong(id));

    Cursor cursor = context.getContentResolver().query(event, null, null, null, null);
    if (cursor != null && cursor.getCount() == 1) {
        //the event exists?
        if (cursor.moveToFirst() && !TextUtils.equals(cursor.getString(cursor.getColumnIndex("deleted")), "1")) {

            cursor.close();
            return true;
        } else {
            return false;
        }
    }
    return false;
}

It works on all the devices.

SKP
  • 410
  • 5
  • 20