I've build an app which allows to synchronize the app specific data with the google calendar.
To add my events to the calendar I've got the following method, which works fine.
private static void addCalendarEvents(Context context, Cursor c) {
if (c.moveToFirst()) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_CALENDAR) == PackageManager.PERMISSION_GRANTED) {
while (!c.isAfterLast() && !c.isBeforeFirst()) {
ContentResolver cr = context.getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, start);
values.put(CalendarContract.Events.DTEND, end);
values.put(CalendarContract.Events.TITLE, title);
values.put(CalendarContract.Events.DESCRIPTION, description);
values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
values.put(CalendarContract.Events.CALENDAR_ID, 1);
values.put(CalendarContract.Events.HAS_ALARM, false);
Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
c.moveToNext();
}
}
}
}
The added events are visible in the google calendar app. My problem is, that I also want to be able to delete (and update) MY EVENTS from the calendar again.
How can I achieve that? I only found solutions to remove all events from the calendar.
Do I have to create an own calendar? How can I automatically let this calendar be synced with the google calendar? Or do I have to save all event ids I added?
I decided to save the calendarEventIds as a additional column in my database as follows which works as a charm:
private static void addCalendarEvents(Context context, Cursor c) {
if (c.moveToFirst()) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_CALENDAR) == PackageManager.PERMISSION_GRANTED) {
while (!c.isAfterLast() && !c.isBeforeFirst()) {
ContentResolver cr = context.getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, start);
values.put(CalendarContract.Events.DTEND, end);
values.put(CalendarContract.Events.TITLE, title);
values.put(CalendarContract.Events.DESCRIPTION, description);
values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
values.put(CalendarContract.Events.CALENDAR_ID, 1);
values.put(CalendarContract.Events.HAS_ALARM, false);
long eventID;
// The row has an event id, so the event should be updated not created
if ((eventID = c.getLong(c.getColumnIndex(LessonDatabaseManagement.KEY_CALENDAR_EVENT_ID))) != -1) {
Uri eventUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID);
cr.update(eventUri, values, null, null);
} else {
// The row hasn't an event id, so the event should be created
Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
eventID = Long.parseLong(uri.getLastPathSegment());
new LessonDatabaseManagement(this)
.updateCalendarEventId(c.getInt(c.getColumnIndex(LessonDatabaseManagement.KEY_ID)), eventID);
}
c.moveToNext();
}
}
}
}
To delete:
private void removeCalendarEvents() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) == PackageManager.PERMISSION_GRANTED) {
Cursor c = new LessonDatabaseManagement(this).getAllCalendarEventIds();
if (c.moveToFirst()) {
while (!c.isAfterLast() && !c.isBeforeFirst()) {
long eventID;
if ((eventID = c.getLong(c.getColumnIndex(LessonDatabaseManagement.KEY_CALENDAR_EVENT_ID))) != -1) {
Uri eventUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID);
this.getContentResolver().delete(eventUri, null, null);
}
c.moveToNext();
}
}
new LessonDatabaseManagement(this).removeAllCalendarEventIds();
}
}
Related
#SuppressLint({"RxLeakedSubscription", "RxSubscribeOnError"})
public static long pushAppointmentsToCalender(Activity curActivity, String title, String addInfo, String place, int status, long startDate, boolean needReminder) {
/***************** Event: note(without alert) *******************/
ContentResolver cr = curActivity.getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, startDate);
values.put(CalendarContract.Events.DTEND, startDate);
values.put(CalendarContract.Events.TITLE, title);
values.put(CalendarContract.Events.DESCRIPTION, addInfo);
values.put(CalendarContract.Events.CALENDAR_ID, startDate);
values.put(CalendarContract.Events.EVENT_TIMEZONE, "Asia/Calcutta");
#SuppressLint("MissingPermission") Uri uriEvent = cr.insert(CalendarContract.Events.CONTENT_URI, values);
long eventID = Long.parseLong(uriEvent.getLastPathSegment());
try {
if (needReminder) {
ContentResolver crreminder = curActivity.getContentResolver();
ContentValues valuesreminder = new ContentValues();
valuesreminder.put(CalendarContract.Reminders.EVENT_ID, eventID);
valuesreminder.put(CalendarContract.Reminders.MINUTES, 15);
valuesreminder.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);
#SuppressLint("MissingPermission") Uri uri = crreminder.insert(CalendarContract.Reminders.CONTENT_URI, valuesreminder);
}
}catch (Exception e){
e.printStackTrace();
}
return eventID;
}
The error i am getting in logs is
2019-03-06 16:29:16.935 23021-23021/com.medikoe.connect.debug W/System.err: android.database.sqlite.SQLiteException
2019-03-06 16:29:16.936 23021-23021/com.medikoe.connect.debug
Event id is created successfully but while inserting uri for reminder is creating sqlite exception . Please help!
Update: I found that this error can be occurred with in two conditions.
If you didn't config your google calendar app in your
phone/emulator this error will occur. Then make sure that you configure the google calendar app with a gmail account before running the app.
If you are passing wrong formatted or false time to the event or reminder. use unix time with correct time zone.
Recently, I also faced same issue. Finally, I found the solution.
First of all, you have to find all logged in gmail id from the device and then select any one gmail account and find its calendar id. After that you have to pass that id to the event query like this....
values.put(Events.CALENDAR_ID, calendarId);
at last call you function
See below method for finding email id's...
public static Hashtable listCalendarId(Context context) {
try {
if (haveCalendarReadWritePermissions((Activity) context)) {
String projection[] = {"_id", "calendar_displayName"};
Uri calendars;
calendars = Uri.parse("content://com.android.calendar/calendars");
ContentResolver contentResolver = c.getContentResolver();
Cursor managedCursor = contentResolver.query(calendars, projection, null, null, null);
if (managedCursor.moveToFirst()) {
String calName;
String calID;
int cont = 0;
int nameCol = managedCursor.getColumnIndex(projection[1]);
int idCol = managedCursor.getColumnIndex(projection[0]);
Hashtable<String, String> calendarIdTable = new Hashtable<>();
do {
calName = managedCursor.getString(nameCol);
calID = managedCursor.getString(idCol);
Log.v(TAG, "CalendarName:" + calName + " ,id:" + calID);
calendarIdTable.put(calName, calID);
cont++;
} while (managedCursor.moveToNext());
managedCursor.close();
return calendarIdTable;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Below is my code to Add calendar Account and then adding Event to that calendar,
AuthenticationManager.getInstance().setContextActivity(this);
AuthenticationManager.getInstance().connect(
new AuthenticationCallback<AuthenticationResult>() {
#Override
public void onSuccess(AuthenticationResult result) {
Log.i(TAG, "onConnectButtonClick - Successfully connected to Office 365");
String type = result.getUserInfo().getIdentityProvider();
String accountOwner = result.getUserInfo().getDisplayableId();
addCalendar(type, accountOwner);
}
#Override
public void onError(final Exception e) {
Log.e(TAG, "onCreate - " + e.getMessage());
}
});
Calendar Method:
public void addCalendar(String type, String accountOwner) {
ContentValues contentValues = new ContentValues();
contentValues.put(CalendarContract.Calendars.ACCOUNT_NAME, accountOwner);
contentValues.put(CalendarContract.Calendars.ACCOUNT_TYPE, type);
contentValues.put(CalendarContract.Calendars.NAME, accountOwner);
contentValues.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "Outlook");
contentValues.put(CalendarContract.Calendars.CALENDAR_COLOR, "232323");
contentValues.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_EDITOR);
contentValues.put(CalendarContract.Calendars.OWNER_ACCOUNT, accountOwner);
contentValues.put(CalendarContract.Calendars.ALLOWED_REMINDERS, "METHOD_ALERT, METHOD_EMAIL, METHOD_ALARM");
contentValues.put(CalendarContract.Calendars.ALLOWED_ATTENDEE_TYPES, "TYPE_OPTIONAL, TYPE_REQUIRED, TYPE_RESOURCE");
contentValues.put(CalendarContract.Calendars.ALLOWED_AVAILABILITY, "AVAILABILITY_BUSY, AVAILABILITY_FREE, AVAILABILITY_TENTATIVE");
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_CALENDAR}, 23);
}
Uri uri = CalendarContract.Calendars.CONTENT_URI;
uri = uri.buildUpon().appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER, "true")
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, accountOwner)
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, type).build();
getContentResolver().insert(uri, contentValues);
}
Adding Event:
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, beginTime.getTimeInMillis());
values.put(CalendarContract.Events.DTEND, endTime.getTimeInMillis());
values.put(CalendarContract.Events.TITLE, "Tech Stores");
values.put(CalendarContract.Events.DESCRIPTION, "Successful Startups");
values.put(CalendarContract.Events.CALENDAR_ID, 10);
values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
values.put(CalendarContract.Events.EVENT_LOCATION, "London");
values.put(CalendarContract.Events.GUESTS_CAN_INVITE_OTHERS, "1");
values.put(CalendarContract.Events.GUESTS_CAN_SEE_GUESTS, "1");
values.put(CalendarContract.Events.ORGANIZER, "azhar#outlook.com");
cr.insert(CalendarContract.Events.CONTENT_URI, values);
The problem is, the event is not getting added to the desired Calendar. I'm not getting any error too. Any correction needed here?
You could add “ CALENDAR_ID ” parameter to the Events, For example:
values.put(CalendarContract.Events. CALENDAR_ID, “”);
For more information, please refer to this link:
CalendarContract.Events
I am saving an event in the device calendar with the below code
ContentResolver cr = getCurrentContext().getContentResolver();
ContentValues values = new ContentValues();
Calendar startDate = Calendar.getInstance();
startDate.setTimeInMillis(contentDatum.getGist().getScheduleStartDate());
Calendar endDate = Calendar.getInstance();
endDate.setTimeInMillis(contentDatum.getGist().getScheduleEndDate());
values.put(CalendarContract.Events.DTSTART, startDate.getTimeInMillis());
values.put(CalendarContract.Events.DTEND, endDate.getTimeInMillis());
values.put(CalendarContract.Events.TITLE, contentDatum.getGist().getTitle());
values.put(CalendarContract.Events.DESCRIPTION, contentDatum.getGist().getDescription());
values.put(CalendarContract.Events.CALENDAR_ID, getCalendarId());
values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
long eventID = Long.parseLong(uri.getLastPathSegment());
Log.e("event", "" + eventID);
setCalendarEventId(eventID);
Intent intent = new Intent(Intent.ACTION_EDIT);
intent.setData(ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID));
getCurrentActivity().startActivityForResult(intent, 0);
I am saving the eventID it returns when it is inserted.
To retrieve the data on the basis of event id, i am using the below code
for (int i = 0; i < calendarEventIds.length; i++) {
long eventID = Long.parseLong(calendarEventIds[i]);
Uri event = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID);
Cursor cursor;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
cursor = getCurrentContext().getContentResolver().query(event, null, null, null);
} else {
cursor = getCurrentActivity().managedQuery(event, null, null, null, null);
}
if (cursor.getCount() == 1) {
if (cursor.moveToFirst()) {
if (cursor.getLong(cursor.getColumnIndex(CalendarContract.Events.DTSTART)) == contentDatum.getGist().getScheduleStartDate()
&& cursor.getLong(cursor.getColumnIndex(CalendarContract.Events.DTEND)) == contentDatum.getGist().getScheduleEndDate()
&& cursor.getString(cursor.getColumnIndex(CalendarContract.Events.TITLE)).equalsIgnoreCase(contentDatum.getGist().getTitle())
&& cursor.getString(cursor.getColumnIndex(CalendarContract.Events.DESCRIPTION)).equalsIgnoreCase(contentDatum.getGist().getDescription())) {
Toast.makeText(getCurrentContext(), "Event already exists in your calendar.", Toast.LENGTH_SHORT).show();
calendarEventExist = true;
}
}
}
}
However I do not the details of the event I added.
I was saving the calendar id's in comma separated string. The below code works perfectly fine for fetching the details of event
if (getCalendarEventId() != null) {
String[] calendarEventIds = getCalendarEventId().split(";");
for (int i = 0; i < calendarEventIds.length; i++) {
long eventID = Long.parseLong(calendarEventIds[i]);
Uri event = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID);
Cursor cursor;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
cursor = getCurrentContext().getContentResolver().query(event, null, null, null);
} else {
cursor = getCurrentActivity().managedQuery(event, null, null, null, null);
}
if (cursor.moveToFirst()) {
do {
if ((cursor.getInt(cursor.getColumnIndex(CalendarContract.Events.DELETED)) == 1)) {
//The added event was deleted and is not visible in calendar but exists in calendar DB
calendarEventExist = false;
break;
}
if (cursor.getString(cursor.getColumnIndex(CalendarContract.Events.TITLE)).equalsIgnoreCase(contentDatum.getGist().getTitle())
&& cursor.getString(cursor.getColumnIndex(CalendarContract.Events.DESCRIPTION)).equalsIgnoreCase(contentDatum.getGist().getDescription())) {
Toast.makeText(getCurrentContext(), "Event already exists in your calendar.", Toast.LENGTH_SHORT).show();
calendarEventExist = true;
break;
}
} while (cursor.moveToNext());
}
}
} else {
calendarEventExist = false;
}
I facing a events details saving in android calendar from the long time. I am able to save the details in devices below android version 2.2.3 but for above it doesn't save to calendar. Here is my code:
Calendar cal = Calendar.getInstance();
Uri events = null;
if(getCalendarUriBase(this)!=null)
{
Uri EVENTS_URI = Uri.parse(getCalendarUriBase(this) + "events");
ContentResolver cr = getContentResolver();
// event insert
long eventdate1=Date.parse(“23/07/2012”);
long eventdate2=Date.parse((“23/07/2012”);
ContentValues values = new ContentValues();
values.put("calendar_id", 1);
values.put("title","Event 1");
values.put("allDay", 0);
values.put("dtstart", eventdate1); // event starts at 11 minutes from now
values.put("dtend", eventdate2); // ends 60 minutes from now
values.put("description", "Description 1");
values.put("eventLocation", "xyz");
values.put("visibility", 0);
values.put("hasAlarm", 1);
try{
try{
events = cr.insert(EVENTS_URI, values);
}catch (Exception e) {
// TODO: handle exception
return false;
}
// reminder insert
Uri REMINDERS_URI = Uri.parse(getCalendarUriBase(this) + "reminders");
values = new ContentValues();
values.put( "event_id", Long.parseLong(events.getLastPathSegment()));
values.put( "method", 1 );
values.put( "minutes", 10 );
cr.insert( REMINDERS_URI, values );
private String getCalendarUriBase(Activity act) {
String calendarUriBase = null;
Uri calendars = Uri.parse("content://calendar/calendars");
Cursor managedCursor = null;
try {
managedCursor = act.managedQuery(calendars, null, null, null, null);
} catch (Exception e) {
}
if (managedCursor != null) {
calendarUriBase = "content://calendar/";
} else {
calendars = Uri.parse("content://com.android.calendar/calendars");
try {
managedCursor = act.managedQuery(calendars, null, null, null, null);
} catch (Exception e) {
}
if (managedCursor != null) {
calendarUriBase = "content://com.android.calendar/";
}
}
return calendarUriBase;
}
******
Where I am missing something. Please help me on it.
I had a similar problem. I think the problem is in
values.put("visibility", 0);
I think that there is no column in database with that name. It's the same with column named transparency. I found it in some tutorials on the net
I am trying to add an event to the android calendar, and I specify that the event will be added to the gmail calendar in order to sync with the Google calendar automatically.
The problem is events added programmatically don't sync with Google calendar, but if I add it manual on the phone it does sync with Google calendar. I don't know why.
This is the code that I use to add the event:
ArrayList<MyCalendar> calendars = new ArrayList<MyCalendar>();
String[] projection = new String[] { "_id", "name" };
Uri calUri = getCalendarURI(false);
Cursor managedCursor = managedQuery(calUri, projection, "selected=1",
null, null);
String calName = null;
String calId = null;
if (managedCursor.moveToFirst()) {
int nameColumn = managedCursor.getColumnIndex("name");
int idColumn = managedCursor.getColumnIndex("_id");
do {
calName = managedCursor.getString(nameColumn);
calId = managedCursor.getString(idColumn);
calendars.add(new MyCalendar(Integer.parseInt(calId), calName));
} while (managedCursor.moveToNext());
}
Toast.makeText(getBaseContext(), calName + " " + calId,
Toast.LENGTH_LONG).show();
Calendar cal = Calendar.getInstance();
ContentValues event = new ContentValues();
event.put("calendar_id", 2);
event.put("title", "Test Event2");
event.put("description", "Hiii Buddy");
long startTime = cal.getTimeInMillis();
long endTime = cal.getTimeInMillis() + 60 * 60 * 1000;
event.put("dtstart", startTime);
event.put("dtend", endTime);
event.put("allDay", 0);
event.put("eventStatus", 1);// tentative 0, confirmed 1 canceled 2
event.put("visibility", 3);// default 0 confidential 1 private 2
// public 3
event.put("transparency", 0);// opaque 0 transparent 1
event.put("hasAlarm", 1); // 0 false, 1 true
Uri eventsUri = getCalendarURI(true);
Uri url = getContentResolver().insert(eventsUri, event);
So the event successfully added to calendar but it doesn't show up in the Google calendar at the web (don't sync) but if I add the event manually it does sync !!!
You can sync your event after adding it by this function,It's worked for me(in API 8 and later):
public static void syncCalendar(Context context, String calendarId) {
ContentResolver cr = context.getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
values.put(CalendarContract.Calendars.VISIBLE, 1);
cr.update(
ContentUris.withAppendedId(getCalendarUri(),
Long.parseLong(calendarId)), values, null, null);
}
Try this code to insert an event into the android calendar as well as google calendar:
ContentValues values = new ContentValues();
cal_id = String.valueOf(p1);
values.put("calendar_id", p1);
values.put("title", title1);
values.put("allDay", 0);
values.put("dtstart", settime);
values.put("dtend", cal.getTimeInMillis()+60*60*1000);
values.put("description", desc1);
values.put("visibility", 0);
values.put("transparency", 0);
values.put("hasAttendeeData", 1);
values.put("hasAlarm", 0);
event = cr.insert(EVENTS_URI, values);
event1=event;
dat1 = event.toString();
long id=-1;
if (event != null)
{
id = Long.parseLong(event.getLastPathSegment());
ContentValues values1 = new ContentValues();
values1.put("event_id", id);
values1.put("method", 1); //METHOD_ALERT
Uri reminder = Uri.parse(getCalendarUriBase(this) + "reminders");
this.getContentResolver().insert(reminder, values1);
if(s.length() > 0 || partmail.length() > 0)
{
//REQUIRES FOLLOWING CODE
This code is used to add the event sync'ed to the google calendar
ContentValues attendees = new ContentValues();
attendees.put("event_id", id);
attendees.put("attendeeEmail", partmail1);
attendees.put("attendeeRelationship", 2);//RELATIONSHIP_ATTENDEE
attendees.put("attendeeStatus", 3); //ATTENDEE_STATUS_INVITED
attendees.put("attendeeType", 1); //TYPE_REQUIRED
id1=(int)id;
alarmid = (int) id;
Uri attendeesUri = null;
if (Integer.parseInt(Build.VERSION.SDK) >= 8 )
{
attendeesUri = Uri.parse("content://com.android.calendar/attendees");
}
else if(Integer.parseInt(Build.VERSION.SDK) < 8)
{
attendeesUri = Uri.parse("content://calendar/attendees");
}
this.getContentResolver().insert(attendeesUri, attendees);
Toast.makeText(this, "Task Scheduled Successfully", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(this, "Could not create Task!", Toast.LENGTH_SHORT);
}
// reminder insert
Uri REMINDERS_URI = Uri.parse(getCalendarUriBase(this) + "reminders");
values = new ContentValues();
values.put( "event_id", id);
values.put( "method", 1 );
values.put( "minutes", 0 );
cr.insert( REMINDERS_URI, values );
Get Calendar's Uri since it differs for API levels such as till 8, greater than 8 and greater than 11.
private String getCalendarUriBase(Context con) {
String calendarUriBase = null;
Uri calendars = Uri.parse("content://calendar/calendars");
Cursor managedCursor = null;
try {
managedCursor = managedQuery(calendars, null, null, null, null);
} catch (Exception e) {
// eat
}
if (managedCursor != null) {
calendarUriBase = "content://calendar/";
} else {
calendars = Uri.parse("content://com.android.calendar/calendars");
try {
managedCursor = managedQuery(calendars, null, null, null, null);
} catch (Exception e) {
// statement to print the stacktrace
}
if (managedCursor != null) {
calendarUriBase = "content://com.android.calendar/";
}
}
return calendarUriBase;
}
Use the google calender api provided here
The above reference is somewhat general as Android doesn’t provide an official API. So, another solution more android specific is An Android Tutorial–Programming with Calendar
which contains a working example too. Also, be careful at Permission Declaration like READ_CALENDAR , WRITE_CALENDAR