Read and write Calendar - android

My objective is to read and write Calendar.
i am able to read data from the content://calendar/calendars and content://calendar/events
String uriString = "content://calendar/calendars";
Log.i("INFO", "Reading content from " + uriString);
readContent(uriString);
uriString = "content://calendar/events";
Log.i("INFO", "Reading content from " + uriString);
readContent(uriString);
private void readContent(String uriString) {
Uri uri = Uri.parse(uriString);
Cursor cursor = mContext.getContentResolver().query(uri, null, null,
null, null);
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
String columnNames[] = cursor.getColumnNames();
String value = "";
String colNamesString = "";
do {
value = "";
for (String colName : columnNames) {
value += colName + " = ";
value += cursor.getString(cursor.getColumnIndex(colName))
+ " ||";
}
Log.e("INFO : ", value);
} while (cursor.moveToNext());
}
}
i am also inserting new record in the calendar like :
String calUriString = "content://calendar/calendars";
ContentValues values = new ContentValues();
values.put("name", "Code Generate Calendar");
values.put("displayName", "Code Generate Calendar");
values.put("hidden", 0);
values.put("color", "-7581685");
values.put("access_level", "700");
values.put("selected", "1");
values.put("timezone", "Asia/Karachi");
Uri calendarUri = context.getContentResolver().insert(
Uri.parse(calUriString), values);
but it is not appearing in the Calendar.
when i going to insert new events in Calendar like :
ContentValues values = new ContentValues();
values.put("calendar_id", 4);
values.put("dtend", "1277337600000");
values.put("dtstart", "1277251200000");
// values.put("title", "first TEst event");
values.put("transparency", 1);
values.put("selected", 1);
values.put("color", "-16380578");
// values.put("lastDate", "6/25/2010");
//values.put("access_level", 700);
values.put("eventStatus", 1);
values.put("eventTimezone", "UTC");
values.put("timezone", "Asia/Karachi");
values.put("allDay", 1);
String eventUriString = "content://calendar/events";
Uri eventUri = context.getContentResolver().insert(
Uri.parse(eventUriString), values);
throwing exception that column is invalid.
how this possible.
Thanks

The calendar content provider is not part of the Android SDK. It has changed between Android releases before and will do so again. It may not work on some devices where they have replaced the default calendar application with their own.
Do not use undocumented content providers.
The solution is the same as the question you asked 32 minutes previously -- use the Google Calendar GData APIs to manipulate the user's calendar.

// To insert event to the calender for android 2.2 and above if less then 2.2 instead of content://com.android.calendar write content://calendar
String calUriString = "content://com.android.calendar/events";
ContentValues values = new ContentValues();
values.put("calendar_id",2); //id, We need to choose from our mobile for primary its 1
values.put("title", "Birthday");
values.put("description", "Go home at 2pm");
values.put("eventLocation", "Home");
long startTime = System.currentTimeMillis() + 1000 * 60 * 60*24; // Next day
values.put("dtstart", startTime);
values.put("dtend", startTime);
values.put("allDay", 1); //If it is bithday alarm or such kind (which should remind me for whole day) 0 for false, 1 for true
values.put("eventStatus", 1); // This information is sufficient for most entries tentative (0), confirmed (1) or canceled (2):
values.put("visibility", 3); // visibility to default (0), confidential (1), private (2), or public (3):
values.put("transparency", 0); // You can control whether an event consumes time opaque (0) or transparent (1).
values.put("hasAlarm", 1); // 0 for false, 1 for true
Uri calendarUri = getApplicationContext().getContentResolver().insert(Uri.parse(calUriString), values);

Dates have been passed since the first question. And today it seems like calendar content provider is well documented. (Maybe since API 14?)
For the short answer to the exception is the difference of the type you give to the column and the type expected. (long expected for dtstart instead of String)
http://developer.android.com/reference/android/provider/CalendarContract.EventsColumns.html#DTSTART
For more information, there is another resource on developer.android.com:
http://developer.android.com/guide/topics/providers/calendar-provider.html

Related

Android calendar custom event color keeps changing to default (blue)

I am developing an android app that programmatically adds some events to the user's default calendar using a ContentResolver.
I also set the color of the events based on the type of the event (in my case: green for holidays, red for workdays). This works fine but after a few minutes all the custom coloring turns to blue (default google calendar event color). I use a Nexus 5X for debugging. Any idea how to solve this?
Screenshots:
Before
After
Code:
// add work day event
if (DateFrom > today.getTimeInMillis() && WorkType == '0') {
ContentResolver cr = context.getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, DateFrom);
values.put(CalendarContract.Events.DTEND, DateTo);
values.put(CalendarContract.Events.TITLE, Team + " (Id: " + Id + ")");
values.put(CalendarContract.Events.DESCRIPTION, "Work Day.");
values.put(CalendarContract.Events.CALENDAR_ID, DEFAULT_CALENDAR_ID);
values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().toString());
values.put(CalendarContract.Events.EVENT_COLOR, Color.RED);
Uri eventUri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
long eventID = Long.parseLong(eventUri.getLastPathSegment());
}
// add day off event
if (DateFrom > today.getTimeInMillis() && WorkType == '2' && IsApproved != null && IsApproved.equals("true")) {
ContentResolver cr = context.getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.ALL_DAY, 1);
values.put(CalendarContract.Events.DTSTART, DateFrom + 3600000);
values.put(CalendarContract.Events.DURATION, "P23H");
values.put(CalendarContract.Events.TITLE, "Day Off!" + " (Id: " + Id + ")");
values.put(CalendarContract.Events.DESCRIPTION, "Day Off");
values.put(CalendarContract.Events.EVENT_COLOR, Color.GREEN);
values.put(CalendarContract.Events.CALENDAR_ID, DEFAULT_CALENDAR_ID);
values.put(CalendarContract.Events.HAS_ALARM, false);
values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().toString());
Uri eventUri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
long eventID = Long.parseLong(eventUri.getLastPathSegment());
}
Documentation says:
EVENT_COLOR
A secondary color for the individual event. This should only be updated by the sync adapter for a given account.
UPD:
The right way is to use EVENT_COLOR_KEY that you can select from CalendarContract.Colors. See documentation

Write and read ID of event Android

I'd like to add an event and get it back programmatically in android. I have two option to add an event to the calender but neither of them good at adding ID to the event. I set the number of the ID into 32 but when I create an event it's ID is growing up. Then how can I add the ID I want?
Option1:
public void InsertAnEvent2(){
Calendar calendarEvent = Calendar.getInstance();
Intent i = new Intent(Intent.ACTION_EDIT);
i.setType("vnd.android.cursor.item/event");
i.putExtra("beginTime", calendarEvent.getTimeInMillis());
i.putExtra("allDay", true);
i.putExtra("rule", "FREQ=YEARLY");
i.putExtra("endTime", calendarEvent.getTimeInMillis() + 60 * 60 * 1000);
i.putExtra("title", "Eskuvo");
i.putExtra("calendar_id",32);
startActivity(i);
}
Option2:
public void Mindencalendar(){
ContentResolver cr = getActivity().getContentResolver();
Calendar calendarEvent = Calendar.getInstance();
Log.d("i'm","here1");
long idk[] = new long[10];
idk[0] = cu.addEventToCalender(cr,"a","b","c",5,calendarEvent.getTimeInMillis());
Log.d("id","id"+idk[0]);
}
public class CalendarUtils {
public static long addEventToCalender(ContentResolver cr, String title, String addInfo, String place, int status,
long startDate) {
String eventUriStr = "content://com.android.calendar/events";
ContentValues event = new ContentValues();
event.put("calendar_id", 32);
event.put("title", title);
event.put("description", addInfo);
event.put("eventLocation", place);
event.put("eventTimezone", "UTC/GMT +2:00");
// For next 1hr
long endDate = startDate + 1000 * 60 * 60;
event.put("dtstart", startDate);
event.put("dtend", endDate);
//If it is bithday alarm or such kind (which should remind me for whole day) 0 for false, 1 for true
// values.put("allDay", 1);
event.put("eventStatus", status);
event.put("hasAlarm", 1);
Uri eventUri = cr.insert(Uri.parse(eventUriStr), event);
long eventID = Long.parseLong(eventUri.getLastPathSegment());
return eventID;
}
}
But maybe the problem is how I try to read these events. Here is my code:
public void ReadFromCalendar(){
Uri EVENTS_URI = Uri.parse("content://com.android.calendar/" + "events");
ContentResolver cr = getActivity().getContentResolver();
Cursor cursor;
cursor = cr.query(EVENTS_URI, null, null, null, null);
//int a = cursor.getCount();
while(cursor.moveToNext()) {
long id = cursor.getLong(cursor.getColumnIndex("calendar_id"));
Log.d("TAG", "ID: " + id);
Uri eventUri = ContentUris.withAppendedId(EVENTS_URI, id);
}
cursor.close();
}
I don't know where do I make a mistake. If anyone has an idea please response.
Can you post the database structure, one of the first thoughts was that your calendar_id column has the auto-increment enabled. In that case you can add another column to your table or alter the existing one, my recommendation is to add another one. But let's see the columns table details.

Android: How to correctly use "CalendarAlerts" to display unique message in Alarms

I have created some events and stored the data in sqlite table but not the system calendar. However, i would like to have an alert/reminder for these events, which is similar to other events that stored in the system.
With reference to the code below, the details of the event are put in the "CalendarAlerts" table and in the broadcast receiver, the alertCursor is used to find the event data with start time close to the current time.
The code worked well if the event is stored in the system with a "long" eventID. But when i try to put data of my sqlite event in "CalendarAlerts" with a "string" eventID. It shows that the data is inserted into the table successfully but i would not query back the result in the "Alert Receiver" class.
Searched google for a while and it seems that not many people are talking on the topic of "CalendarAlerts". Great if anyone would share the experience on this issue.
Setting the AlarmManager
Uri alertUri = CalendarAlerts.CONTENT_URI;
long alarmMillis = (long) mStart - (long)(min*60*1000);
ContentValues alertValues =AlertUtils.makeContentValues(eventIdentifier,mStart, mEnd,alarmMillis, 0);
context.getContentResolver().insert(alertUri, alertValues);
public static ContentValues makeContentValues(String eventId, long begin, long end,
long alarmTime, int minutes) {
ContentValues values = new ContentValues();
values.put(CalendarAlerts.EVENT_ID, eventId);
values.put(CalendarAlerts.BEGIN, begin);
values.put(CalendarAlerts.END, end);
values.put(CalendarAlerts.ALARM_TIME, alarmTime);
long currentTime = System.currentTimeMillis();
values.put(CalendarAlerts.CREATION_TIME, currentTime);
values.put(CalendarAlerts.RECEIVED_TIME, 0);
values.put(CalendarAlerts.NOTIFY_TIME, 0);
values.put(CalendarAlerts.STATE, CalendarAlerts.STATE_SCHEDULED);
values.put(CalendarAlerts.MINUTES, minutes);
return values;
}
AlertReceiver.java
Cursor alertCursor = cr.query(CalendarAlerts.CONTENT_URI, ALERT_PROJECTION,
(ACTIVE_ALERTS_SELECTION + currentMillis), ACTIVE_ALERTS_SELECTION_ARGS,
ACTIVE_ALERTS_SORT);
You can use this code which works for me :
ContentResolver cr = getActivity().getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, startMillis);
values.put(CalendarContract.Events.TITLE, title);
values.put(CalendarContract.Events.DESCRIPTION, "description");
TimeZone timeZone = TimeZone.getDefault();
values.put(CalendarContract.Events.EVENT_TIMEZONE, timeZone.getID());
// default calendar
values.put(CalendarContract.Events.CALENDAR_ID, 1);
//for one hour
values.put(CalendarContract.Events.DURATION, "+P1H");
values.put(CalendarContract.Events.HAS_ALARM, 1);
// cr.delete(CalendarContract.Events.CONTENT_URI, null,null);
// insert event to calendar
Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);

How to bulk delete events from the Device calendar by app id, and not by an array of event ids

This is how I create calendar events from within my app:
for(CalendarEventDescriptor calendarEventDescriptor : calendarEventDescriptors.values()) {
if(calendarEventDescriptor.startMilliseconds>now){
values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, calendarEventDescriptor.startMilliseconds);
values.put(CalendarContract.Events.DTEND, calendarEventDescriptor.endMilliseconds);
values.put(CalendarContract.Events.TITLE, calendarEventDescriptor.title);
values.put(CalendarContract.Events.DESCRIPTION, calendarEventDescriptor.description);
values.put(CalendarContract.Events.CALENDAR_ID, 1);
values.put(CalendarContract.Events.EVENT_TIMEZONE, timeZone);
uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
calendarEventDescriptor.eventId = Long.parseLong(uri.getLastPathSegment());
}
}
At the time or writing, I store an array of all the event Ids that I've created, so that when the user flicks a switch, I loop through them and delete them from the Calendar.
for(long eventId : eventIds) {
if(eventId>0){
Uri deleteUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventId);
rowsDeleted += application.getContentResolver().delete(deleteUri, null, null);
}
}
It occurred to me that it might be possible to put a custom value for one of the CalendarContract.Events. columns so that I can do the deletion for all of the events at once, and that I don't have to remember their ids (I always delete them all, never delete certain ones)
Is that possible and which CalendarContract.Events. column should I use and how do I do the deletion then?
Nice question! I agree, that extra-property in ContentValues is the way to go in this case.
I've done it by re-using CalendarContract.Events.CUSTOM_APP_PACKAGE, as something invisible for the user and, so far, no side effects found:
So I'm creating Events, like you do:
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.CALENDAR_ID, 1);
values.put(CalendarContract.Events.DTSTART, ...);
values.put(CalendarContract.Events.DTEND, ...);
values.put(CalendarContract.Events.TITLE, ...);
values.put(CalendarContract.Events.DESCRIPTION, ....);
values.put(CalendarContract.Events.CUSTOM_APP_PACKAGE, getApplicationContext().getPackageName());
values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
cr.insert(CalendarContract.Events.CONTENT_URI, values);
And then once I need to delete all of them, I call:
Cursor cursor = cr
.query(CalendarContract.Events.CONTENT_URI,
new String[] { CalendarContract.Events._ID, CalendarContract.Events.CUSTOM_APP_PACKAGE },
null, null, null);
cursor.moveToFirst();
String idsToDelete = "";
for (int i = 0; i < cursor.getCount(); i++) {
// it might be also smart to check CALENDAR_ID here
if (getApplicationContext().getPackageName().equals(cursor.getString(1))) {
idsToDelete += String.format("_ID = %s OR ", cursor.getString(0));
}
cursor.moveToNext();
}
if (idsToDelete.endsWith(" OR ")) {
idsToDelete = idsToDelete.substring(0, idsToDelete.length()-4);
}
cr.delete(CalendarContract.Events.CONTENT_URI, idsToDelete, null);
I hope, it helps
You can use ContentProviderOperation with applyBatch to perform multiple deletes/inserts in a single transaction.
Check this SO answer for code sample.
after a long long research, I've got a sort of new doc of google calendar
you can add multiple args to a selection allowing you to find all desired rows and delete them all at once
val operationList = ArrayList<ContentProviderOperation>()
var contentProviderOperation: ContentProviderOperation
appointments.forEach {
contentProviderOperation = ContentProviderOperation
.newDelete(CalendarContract.Events.CONTENT_URI)
.withSelection(CalendarContract.Events.ORIGINAL_SYNC_ID + " =?", arrayOf(it.id))
.build()
operationList.add(contentProviderOperation)
}
contentResolver.applyBatch(CalendarContract.AUTHORITY, operationList)

Event not being added to Calendar on some Android phones

I am using below code to add events to calendar on android
public void addEvent(String datetime) {
String eventdate;
{
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm");
final Calendar cal = Calendar.getInstance();
try {
cal.setTime(formatter.parse(datetime));
eventdate = cal.get(Calendar.YEAR)+"/"+cal.get(Calendar.MONTH)+"/"+cal.get(Calendar.DAY_OF_MONTH)+" "+cal.get(Calendar.HOUR_OF_DAY)+":"+cal.get(Calendar.MINUTE);
//Log.e("Event date ", eventdate);
} catch (Exception e) {
Log.e("Catch ", "",e);
}
ContentValues event = new ContentValues();
event.put("calendar_id", 3);
event.put("_id", eventid);
event.put("title", mytitle);
event.put("description", mydescription);
event.put("eventTimezone", TimeZone.getDefault().getID());
event.put("dtstart", cal.getTimeInMillis());
event.put("dtend", cal.getTimeInMillis()+60*60*1000);
event.put("hasAlarm", 1); // 0 for false, 1 for true
String eventUriString = "content://com.android.calendar/events";
Uri eventUri = getApplicationContext()
.getContentResolver()
.insert(Uri.parse(eventUriString), event);
System.out.println("event"+eventUri);
}
the following code adds event to my HTC phone running android lollipop but it returns null on Phones like Micromax and Samsung running android Jellybean. What can be the reason for this behavior? Do I need to turn anything on from settings?
try using the constants provided by the Events class.
ContentResolver cr = yourContext.getContentResolver();
ContentValues event = new ContentValues();
event.put(Events.DTSTART, cal.getTimeInMillis());
event.put(Events.DTEND, cal.getTimeInMillis() + 60 * 60 * 1000);
event.put(Events.TITLE, mytitle);
event.put(Events.DESCRIPTION, mydescription);
event.put(Events.CALENDAR_ID, calID);
event.put(Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
...
Uri uri = cr.insert(Events.CONTENT_URI, event);
The Event id of this inserted event can be get from this method
long eventID = Long.parseLong(uri.getLastPathSegment());
Check the title Adding Events in Calendar Provider
http://developer.android.com/guide/topics/providers/calendar-provider.html
If you want to insert an _id to the Event, you should check if it is already there
Uri event = ContentUris.withAppendedId(Events.CONTENT_URI, _id);
Cursor cursor = managedQuery(event, null, null, null);
if (cursor.getCount() == 1) {
//the event exists.. so may be you want to update it
} else {
// you can insert your id
}

Categories

Resources