I am querying the CalendarContract.Instances table to read all calendar event instances within a time interval (curr_time, next_time), as shown in the code below. This code works when the calendar entries have been around for a while. However, if I add a new entry, change an existing entry, or delete it, I get some old/stale entries (e.g., a new entry is not returned when it should be, or the unmodified/deleted entry is still returned), and this happens consistently. This problem occurs on my phone (Samsung S7) but does not appear to occur on the Android emulator. I am wondering if anyone else has seen this problem, or what I might be doing wrong. Any help is appreciated. Thanks.
try {
Uri.Builder builder = Instances.CONTENT_URI.buildUpon();
ContentUris.appendId(builder, curr_time);
ContentUris.appendId(builder, next_time);
String[] INSTANCE_PROJECTION = new String[]{Instances.EVENT_ID,
Instances.TITLE, Instances.BEGIN, Instances.END};
Uri uri = builder.build();
cur = cr.query(uri, INSTANCE_PROJECTION, null, null,null);
if (cur != null) {
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(Instances.EVENT_ID));
String title = cur.getString(cur.getColumnIndex(Instances.TITLE));
long start = cur.getLong(cur.getColumnIndex(Instances.BEGIN));
long end = cur.getLong(cur.getColumnIndex(Instances.END));
Calendar calendar = Calendar.getInstance();
DateFormat formatter = SimpleDateFormat
.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
calendar.setTimeInMillis(start);
Date start_date = calendar.getTime();
calendar.setTimeInMillis(end);
Date end_date = calendar.getTime();
Log.i(log_tag, "Event: " + id + "\t" + title + "\t" +
start + " " + formatter.format(start_date) + "\t" +
end + " " + formatter.format(end_date));
}
}
} catch (SecurityException e) {
// no permission to read calendars
} finally {
if (cur != null)
cur.close();
}
I would ask You for a help. Now I am writing an app, which takes current events from Google calendars. But problem is there, when I'm trying to output events from more than one calendar. I know, that I'm doing something wrong, but really, can't get in the problem..
public class Main extends Activity {
//TextView mInfo;
TextView mEvents;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//mInfo = (TextView)findViewById(R.id.info);
mEvents = (TextView)findViewById(R.id.events);
String[] calendarName = {"Calendar1", "Calendar2", "Calendar3", "Calendar4", "Calendar5"};
readCalendars(calendarName);
}
private void readCalendars(String[] calendarName)
{
String[] projection =
new String[]{
CalendarContract.Calendars._ID,
CalendarContract.Calendars.NAME,
CalendarContract.Calendars.ACCOUNT_NAME,
CalendarContract.Calendars.ACCOUNT_TYPE};
Cursor calCursor =
getContentResolver().
query(CalendarContract.Calendars.CONTENT_URI,
projection,
CalendarContract.Calendars.VISIBLE + " = 1",
null,
CalendarContract.Calendars._ID + " ASC");
long calId = -1;
//String calendarAccount = "";
for(int i = 0; i 0)
{
if(cursor.moveToFirst())
{
do
{
long eventId = cursor.getLong(3);
events += getEventInfo(eventId,cursor.getLong(1),cursor.getLong(2),cursor.getString(4),cursor.getString(5),cursor.getString(6)) + "\n";
} while(cursor.moveToNext());
}
}
mEvents.setText(events);
}
}
#SuppressLint("SimpleDateFormat")
private String getEventInfo(long eventId,long startTime, long endTime,String description, String location,String title)
{
String eventInfo = "";
{
DateFormat df = new SimpleDateFormat("HH:mm");
String start = df.format( new Date(startTime));
String end = df.format( new Date(endTime));
eventInfo = start + "-" + end + " Class: "+ location + "\nLecture: " + title + "\nLecturer: " + description;
}
return eventInfo;
}
}
Tried to output all events with loop, but does not helps. If I pass in calendarName[i], where i is one of existing calendars, I get output of calendar, which I asked for, but that's only one calendar, but for example, I need to output 5 calendars.
Tried to do anything with ListView - failure again.
Hope, You would help with this problem or help somehow how to resolve it..
The CalendarContract.Calendars.CONTENT_URI can be used to retrieve calendars, but not actual events for those calendars. Once you have the calendar id, you must use either of the following URIs for event information:
CalendarContract.Events.CONTENT_URI
CalendarContract.Instances.CONTENT_URI
I have working in android calender. i have add event in Calender programmatically using android app.
I have Also Refer this links :IllegalArgumentException: Unknown URL content://com.android.calendar/events when inserting an event to the calendar on Android
Adding events to native calendar is not working
but is not working in my code .
my Code is:
ContentValues contentEvent = new ContentValues();
// Particular Calendar in which we need to add Event
contentEvent.put("calendar_id", AlarmId);
// Title/Caption of the Event
contentEvent.put("title", "Wedding");
// Description of the Event
contentEvent.put("description", "Wedding Party");
// Venue/Location of the Event
contentEvent.put("eventLocation", "New York");
// Start Date of the Event with Time
contentEvent.put("dtstart", l);
// End Date of the Event with Time
contentEvent.put("dtend", l+60*1000);
// All Day Event
contentEvent.put("allDay", 1);
// Set alarm for this Event
contentEvent.put("hasAlarm",1);
contentEvent.put("eventTimezone", android.text.format.Time.getCurrentTimezone());
Uri eventsUri = getCalendarURI(false);
// event is added successfully
getContentResolver().insert(eventsUri, contentEvent);
// Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
public Uri getCalendarURI(boolean eventUri) {
Uri calendarURI = null;
if (android.os.Build.VERSION.SDK_INT <= 7) {
calendarURI = (eventUri) ? Uri.parse("content://calendar/events")
: Uri.parse("content://calendar/calendars");
} else {
calendarURI = (eventUri) ? Uri
.parse("content://com.android.calendar/events") : Uri
.parse("content://com.android.calendar/calendars");
}
return calendarURI;
}
My issue Is: When i have run my application that time this error have been generated. so how can i solve this error ?
error is:
java.lang.IllegalArgumentException: Unknown URL content://com.android.calendar/
thank you in Advance
Calendar cal = Calendar.getInstance();
long l = cal.getTimeInMillis();
long cal_Id = 1;
**// Also Here Use Cal_Id = 1 not parse another value**
ContentResolver CR = getContentResolver();
ContentValues calEvent = new ContentValues();
calEvent.put(CalendarContract.Events.CALENDAR_ID, cal_Id); // XXX pick)
calEvent.put(CalendarContract.Events.TITLE, " Demo Data");
calEvent.put(CalendarContract.Events.DTSTART,l);
calEvent.put(CalendarContract.Events.DTEND, l+60 * 1000);
calEvent.put(CalendarContract.Events.EVENT_TIMEZONE, "Indian/Christmas");
// Here use the proper time zone of area wise and solve this error
Uri uri = CR.insert(URL, calEvent);
int id = Integer.parseInt(uri.getLastPathSegment());
Toast.makeText(this, "Created Calendar Event " + id,
Toast.LENGTH_SHORT).show();
try this :
Uri calendars = getCalendarURI(true);
public Uri getCalendarURI(boolean eventUri) {
Uri calendarURI = null;
if (android.os.Build.VERSION.SDK_INT <= 7) {
calendarURI = (eventUri) ? Uri.parse("content://calendar/events")
: Uri.parse("content://calendar/calendars");
} else {
calendarURI = (eventUri) ? Uri
.parse("content://com.android.calendar/events") : Uri
.parse("content://com.android.calendar/calendars");
}
return calendarURI;
}
You can try this way :
Calendar cal = Calendar.getInstance();
Intent intent = new Intent(Intent.ACTION_EDIT);
intent.setType("vnd.android.cursor.item/event");
intent.putExtra("beginTime", cal.getTimeInMillis());
intent.putExtra("allDay", true);
intent.putExtra("rrule", "FREQ=YEARLY");
intent.putExtra("endTime", cal.getTimeInMillis()+60*60*1000);
intent.putExtra("title", "A Test Event from android app");
startActivity(intent);
or you can find in this topic:
How to add calendar events in Android?
I'm trying to build a simple example application that counts the number of events on a specific calendar (I know the CALENDAR_DISPLAY_NAME of the Calendar) for today only.
I believe I need to query todays events with CalendarContract, and then count the number of rows in the cursor?
Is that correct? What would be the minimal, most efficient way to do the query on the single calendar, and have it return only the minimal possible set of data (event id only?) ?
This is the solution I arrived at:
First find the Calendar ID from the known name.
Then:
private Cursor getEventInstancesCursor() { // Query for a list of GQueues Calendar instances today
// Set Calendar variable for start and end of today.
Calendar startOfDay = Calendar.getInstance();
int thisYear = startOfDay.get(Calendar.YEAR);
int thisMonth = startOfDay.get(Calendar.MONTH);
int thisDay = startOfDay.get(Calendar.DAY_OF_MONTH);
startOfDay.set(thisYear, thisMonth, thisDay, 0, 0, 0);
long startMillis = startOfDay.getTimeInMillis();
Calendar endOfDay = Calendar.getInstance();
endOfDay.set(thisYear, thisMonth, thisDay, 23, 59, 59);
long endMillis = endOfDay.getTimeInMillis();
long GQueuesCalID = getGQueuesCalID();
Cursor eventsCursor = null;
ContentResolver eventsCR = getContentResolver();
String selection = CalendarContract.Instances.CALENDAR_ID + " = ?";
String calIDString = String.valueOf(GQueuesCalID);
String[] selectionArgs = {calIDString};
try {
return eventsCursor = eventsCR.query(
CalendarContract.Instances.CONTENT_URI.buildUpon()
.appendPath(Long.toString(startMillis))
.appendPath(Long.toString(endMillis))
.build(),
InstancesQuery.PROJECTION,
selection,
selectionArgs,
null);
} catch (Exception e) {
Log.e(TAG, "Error querying calendar API", e);
return null;
}
}
Then just count the cursor rows.
I want to add calendar events programmatically (directly) in android 4+. Is it this possible to be tested on emulator? I don't own an android phone. Some sample code would be appreciated. I read Calendar Provider of android developers but I'm confused. How can I add events to the default calendar of a user? I don't need to be synced.
EDIT: I do not want to launch an event adding Intent. Instead I want to add them completely from code and not launch another activity. I need to be able to test on an emulator that the events will be added to the main calendar of the default user of the device. How do I set up an emulator to view the default calendar of the user?
Here is a working example of what i eventually made it:
ContentResolver cr = ctx.getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, dtstart);
values.put(CalendarContract.Events.TITLE, title);
values.put(CalendarContract.Events.DESCRIPTION, comment);
TimeZone timeZone = TimeZone.getDefault();
values.put(CalendarContract.Events.EVENT_TIMEZONE, timeZone.getID());
// Default calendar
values.put(CalendarContract.Events.CALENDAR_ID, 1);
values.put(CalendarContract.Events.RRULE, "FREQ=DAILY;UNTIL="
+ dtUntill);
// Set Period for 1 Hour
values.put(CalendarContract.Events.DURATION, "+P1H");
values.put(CalendarContract.Events.HAS_ALARM, 1);
// Insert event to calendar
Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
where dtuntil is
SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyyMMdd");
Calendar dt = Calendar.getInstance();
// Where untilDate is a date instance of your choice, for example 30/01/2012
dt.setTime(untilDate);
// If you want the event until 30/01/2012, you must add one day from our day because UNTIL in RRule sets events before the last day
dt.add(Calendar.DATE, 1);
String dtUntill = yyyyMMdd.format(dt.getTime());
Ref: Recurrence Rule
I believe the section you are looking for is Using an intent to insert an event. In this section it describes how to create an intent for the event you want to add and then the default calender program on the emulator will respond and add it. You may have to set up a dummy profile so that the calendar program will start if you actually want to see that it receives the correct information.
Code from Android Dev Site:
Calendar beginTime = Calendar.getInstance();
beginTime.set(2012, 0, 19, 7, 30);
Calendar endTime = Calendar.getInstance();
endTime.set(2012, 0, 19, 8, 30);
Intent intent = new Intent(Intent.ACTION_INSERT)
.setData(Events.CONTENT_URI)
.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis())
.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis())
.putExtra(Events.TITLE, "Yoga")
.putExtra(Events.DESCRIPTION, "Group class")
.putExtra(Events.EVENT_LOCATION, "The gym")
.putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY)
.putExtra(Intent.EXTRA_EMAIL, "rowan#example.com,trevor#example.com");
startActivity(intent);
Dont Forget to add Permission to Manifest
<uses-permission android:name="android.permission.READ_CALENDAR"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
Code from :->Android Dev Site
long calID = 3; // Make sure to which calender you want to add event
long startMillis = 0;
long endMillis = 0;
Calendar beginTime = Calendar.getInstance();
beginTime.set(2012, 9, 14, 7, 30);
startMillis = beginTime.getTimeInMillis();
Calendar endTime = Calendar.getInstance();
endTime.set(2012, 9, 14, 8, 45);
endMillis = endTime.getTimeInMillis();
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(Events.DTSTART, startMillis);
values.put(Events.DTEND, endMillis);
values.put(Events.TITLE, "Hackathon");
values.put(Events.DESCRIPTION, "do some code");
values.put(Events.CALENDAR_ID, calID);
values.put(Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
Uri uri = cr.insert(Events.CONTENT_URI, values);
// get the event ID that is the last element in the Uri
long eventID = Long.parseLong(uri.getLastPathSegment());
Using this code, you can programmatically add an event to device calendar. I have tested in Marshmallow, and it works fine for me.
private void addToDeviceCalendar(String startDate,String endDate, String title,String description, String location) {
String stDate = startDate;
String enDate = endDate;
GregorianCalendar calDate = new GregorianCalendar();
//GregorianCalendar calEndDate = new GregorianCalendar();
SimpleDateFormat originalFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
SimpleDateFormat targetFormat = new SimpleDateFormat("yyyy,MM,dd,HH,mm");
Date date,edate;
try {
date = originalFormat.parse(startDate);
stDate=targetFormat.format(date);
} catch (ParseException ex) {}
long startMillis = 0;
long endMillis = 0;
String dates[] = stDate.split(",");
SD_YeaR = dates[0];
SD_MontH = dates[1];
SD_DaY = dates[2];
SD_HouR = dates[3];
SD_MinutE = dates[4];
/*Log.e("YeaR ", SD_YeaR);
Log.e("MontH ",SD_MontH );
Log.e("DaY ", SD_DaY);
Log.e(" HouR", SD_HouR);
Log.e("MinutE ", SD_MinutE);*/
calDate.set(Integer.parseInt(SD_YeaR), Integer.parseInt(SD_MontH)-1, Integer.parseInt(SD_DaY), Integer.parseInt(SD_HouR), Integer.parseInt(SD_MinutE));
startMillis = calDate.getTimeInMillis();
/*
try {
edate = originalFormat.parse(endDate);
enDate=targetFormat.format(edate);
} catch (ParseException ex) {}
String end_dates[] = endDate.split(",");
String ED_YeaR = end_dates[0];
String ED_MontH = end_dates[1];
String ED_DaY = end_dates[2];
String ED_HouR = end_dates[3];
String ED_MinutE = end_dates[4];
calEndDate.set(Integer.parseInt(ED_YeaR), Integer.parseInt(ED_MontH)-1, Integer.parseInt(ED_DaY), Integer.parseInt(ED_HouR), Integer.parseInt(ED_MinutE));
endMillis = calEndDate.getTimeInMillis();*/
try {
ContentResolver cr = getActivity().getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, startMillis);
values.put(CalendarContract.Events.DTEND, calDate.getTimeInMillis() + 60 * 60 * 1000);
values.put(CalendarContract.Events.TITLE, title);
values.put(CalendarContract.Events.DESCRIPTION, description);
values.put(CalendarContract.Events.EVENT_LOCATION,location);
values.put(CalendarContract.Events.HAS_ALARM,1);
values.put(CalendarContract.Events.CALENDAR_ID, 1);
values.put(CalendarContract.Events.EVENT_TIMEZONE, Calendar.getInstance()
.getTimeZone().getID());
System.out.println(Calendar.getInstance().getTimeZone().getID());
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
return;
}
Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
long eventId = Long.parseLong(uri.getLastPathSegment());
Log.d("Ketan_Event_Id", String.valueOf(eventId));
} catch (Exception e) {
e.printStackTrace();
}
}
Here is the way to ask user to which calendar the event has to be added. As my requirement was this and didn't find the solution at one place. I have summarized and came up with this solution, hope it helps someone :)
final ContentResolver cr = this.getContentResolver();
Cursor cursor ;
if (Integer.parseInt(Build.VERSION.SDK) >= 8 )
cursor = cr.query(Uri.parse("content://com.android.calendar/calendars"), new String[]{ "_id", "calendar_displayName" }, null, null, null);
else
cursor = cr.query(Uri.parse("content://calendar/calendars"), new String[]{ "_id", "displayname" }, null, null, null);
if (cursor != null && cursor.moveToFirst() ) {
final String[] calNames = new String[cursor.getCount()];
final int[] calIds = new int[cursor.getCount()];
for (int i = 0; i < calNames.length; i++) {
calIds[i] = cursor.getInt(0);
calNames[i] = cursor.getString(1);
cursor.moveToNext();
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
final long startDate = sdf.parse(slotData.getSlot_date() + " " + slotData.getSlot_from()).getTime();
final long endDate = sdf.parse(slotData.getSlot_date() + " " + slotData.getSlot_to()).getTime();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select any one");
builder.setSingleChoiceItems(calNames, -1, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ContentValues cv = new ContentValues();
cv.put("calendar_id", calIds[which]);
cv.put("title", title);
cv.put("dtstart", startDate);
cv.put("hasAlarm", 1);
cv.put("dtend", endDate);
cv.put("eventTimezone", TimeZone.getDefault().getID());
Uri newEvent ;
if (Integer.parseInt(Build.VERSION.SDK) >= 8 )
newEvent = cr.insert(Uri.parse("content://com.android.calendar/events"), cv);
else
newEvent = cr.insert(Uri.parse("content://calendar/events"), cv);
if (newEvent != null) {
long id = Long.parseLong( newEvent.getLastPathSegment() );
ContentValues values = new ContentValues();
values.put( "event_id", id );
values.put( "method", 1 );
values.put( "minutes", 15 ); // 15 minutes
if (Integer.parseInt(Build.VERSION.SDK) >= 8 )
cr.insert( Uri.parse( "content://com.android.calendar/reminders" ), values );
else
cr.insert( Uri.parse( "content://calendar/reminders" ), values );
}
dialog.cancel();
}
});
builder.create().show();
}
if (cursor != null) {
cursor.close();
}
After reading several posts and after a few tries.
I finally found this method to work well on Android 8 and 10.
My code:
public void addEventToCalendar() {
Context myContext = getContext();
String[] projection = {"_id", "calendar_displayName"};
Cursor calCursor = myContext.getContentResolver().query(CalendarContract.Calendars.CONTENT_URI, projection, CalendarContract.Calendars.VISIBLE + " = 1 AND " + CalendarContract.Calendars.IS_PRIMARY + "=1", null, CalendarContract.Calendars._ID + " ASC");
if(calCursor.getCount() <= 0){
calCursor = myContext.getContentResolver().query(CalendarContract.Calendars.CONTENT_URI, projection, CalendarContract.Calendars.VISIBLE + " = 1", null, CalendarContract.Calendars._ID + " ASC");
}
while (calCursor.moveToNext()) {
long id = calCursor.getLong(calCursor.getColumnIndexOrThrow(CalendarContract.Calendars._ID));
long startMillis;
long endMillis;
Calendar beginTime = Calendar.getInstance();
beginTime.set(2021, 9, 22, 15, 30);
startMillis = beginTime.getTimeInMillis();
Calendar endTime = Calendar.getInstance();
endTime.set(2021, 9, 22, 16, 45);
endMillis = endTime.getTimeInMillis();
ContentResolver cr = Objects.requireNonNull(getActivity()).getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, startMillis);
values.put(CalendarContract.Events.DTEND, endMillis);
values.put(CalendarContract.Events.TITLE, "My event");
values.put(CalendarContract.Events.DESCRIPTION, "Nice description");
values.put(CalendarContract.Events.CALENDAR_ID, id);
Log.i("ID","my Id"+ id);
values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
long eventID = Long.parseLong(uri.getLastPathSegment());
}
}
I was able to test on different phones and the insertion is done on the google calendar as well as on a basic android calendar.
Normally this method makes sure to insert the event (s) in all the calendars available on the device. I couldn't test it but I have high hopes.
Agree with above all answers but import is calender Id. you can not use 1 as samsung phone uses 1 for their calender(S Planner).So calender ID is id for which email you want event. you can get calender id by following code for specific event
int calenderId=-1;
String calenderEmaillAddress="xxx#gmail.com";
String[] projection = new String[]{
CalendarContract.Calendars._ID,
CalendarContract.Calendars.ACCOUNT_NAME};
ContentResolver cr = activity.getContentResolver();
Cursor cursor = cr.query(Uri.parse("content://com.android.calendar/calendars"), projection,
CalendarContract.Calendars.ACCOUNT_NAME + "=? and (" +
CalendarContract.Calendars.NAME + "=? or " +
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME + "=?)",
new String[]{calenderEmaillAddress, calenderEmaillAddress,
calenderEmaillAddress}, null);
if (cursor.moveToFirst()) {
if (cursor.getString(1).equals(calenderEmaillAddress))
calenderId=cursor.getInt(0); //youre calender id to be insered in above 2 answer
}