I am trying to add an event on a calendar that i created programmatically like this
var uri = CalendarContract.Calendars.ContentUri; ContentValues val = new ContentValues();
val.Put(CalendarContract.Calendars.InterfaceConsts.CalendarAccessLevel, CalendarAccess.AccessOwner.ToString());
val.Put(CalendarContract.Calendars.Name, "Mary");
val.Put(CalendarContract.Calendars.InterfaceConsts.Visible, true);
val.Put(CalendarContract.Calendars.InterfaceConsts.SyncEvents, true);
val.Put(CalendarContract.Calendars.InterfaceConsts.CalendarColor, "0xff00ffff");
val.Put(CalendarContract.Calendars.InterfaceConsts.CalendarDisplayName, "Mary");
uri = uri.BuildUpon()
.AppendQueryParameter(CalendarContract.CallerIsSyncadapter, "true")
.AppendQueryParameter(CalendarContract.Calendars.InterfaceConsts.AccountName, AccountName)
.AppendQueryParameter(CalendarContract.Calendars.InterfaceConsts.AccountType, CalendarContract.AccountTypeLocal)
.Build();
var calresult = ContentResolver.Insert(uri, val);
calID = int.Parse(calresult.LastPathSegment);
AddCalendarEvent( calID);
it gets added successfully and I am able to see this calendar
I am adding event like this,
ContentValues eventValues = new ContentValues();
eventValues.Put(CalendarContract.Events.InterfaceConsts.CalendarId, calID);
eventValues.Put(CalendarContract.Events.InterfaceConsts.Title, "Test Event from M4A");
eventValues.Put(CalendarContract.Events.InterfaceConsts.Description, "This is an event created from Mono for Android");
eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtstart, GetDateTimeMS(2013, 9, 15, 10, 0));
eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtend, GetDateTimeMS(2013, 9, 15, 11, 0));
// GitHub issue #9 : Event start and end times need timezone support.
// https://github.com/xamarin/monodroid-samples/issues/9
eventValues.Put(CalendarContract.Events.InterfaceConsts.EventTimezone, "UTC");
eventValues.Put(CalendarContract.Events.InterfaceConsts.EventEndTimezone, "UTC");
var uri = ContentResolver.Insert(CalendarContract.Events.ContentUri, eventValues);
Console.WriteLine("Uri for new event: {0}", uri);
My problem is that when I am trying to open this event to see the description, it gives me an error that "Unfortunately the calendar has stopped". I am able to open the event when it is added to the default calendar. What wrong am I doing in the creating the calendar??
I followed the code from this blog, http://www.derekbekoe.co.uk/blog/16-using-the-android-4-0-calendar-api#part4 and still it is giving me the same error. I am using Android 4.2.2
When creating the calendar, you should be specifying the OWNER_ACCOUNT. This link from the Android docs shows you the fields that must be included when inserting a new calendar. (http://developer.android.com/reference/android/provider/CalendarContract.Calendars.html)
This is similarly the case for adding a new event to your calendar. (http://developer.android.com/reference/android/provider/CalendarContract.Events.html)
Also, it is not clear from your code but currently it looks like you are using the default uri for events, CalendarContract.Events.ContentUri. You may have to build the event uri also, just like you have done for creating the calendar, and then use this new uri when you insert the event with ContentResolver.Insert.
The problem was the calendar was not liking the color code set. I used Android.Graphics.Color.Red instead of the hash code for color. It works well with that
Related
I am developing an application in which i am setting reminder using following code :
// Creation of Event.
ContentValues eventValues = new ContentValues();
// Set calendar as 1 for default calendar.
eventValues.put(Events.CALENDAR_ID, 1);
// Set title as user define.
eventValues.put(Events.TITLE, "Reminder");
// Set description as user define.
eventValues.put(Events.DESCRIPTION, "You set the reminder.");
// Set location as user define.
eventValues.put(Events.EVENT_TIMEZONE, "India");
// Set start time as system time or time converted in milliseconds.
eventValues.put(Events.DTSTART, startMillis);
// Set status of event as 1.
eventValues.put("eventStatus", 1);
// Set visibility of event as 3 (public).
eventValues.put("visibility", 3);
// Set transparency as 0. No other app seen through reminder.
eventValues.put("transparency", 0);
// Set alarm as 1. Ringing.
eventValues.put(Events.HAS_ALARM, 1);
// Set Event in calendar.
Uri eventUri = getContentResolver().insert(Uri.parse(eventUriString), eventValues);
// Getting ID of event in Long.
long eventID = Long.parseLong(eventUri.getLastPathSegment());
/***************** Event: Reminder(with alert) Adding reminder to event *******************/
// String to access default google calendar of device for reminder setting.
String reminderUriString = "content://com.android.calendar/reminders";
ContentValues reminderValues = new ContentValues();
// Set reminder on Event ID.
reminderValues.put("event_id", eventID);
// Set reminder minute before.
reminderValues.put("minutes", 10);
// Set method of reminder
reminderValues.put("method", 1);
#SuppressWarnings("unused")
//Setting reminder in calendar on Event.
Uri reminderUri = getContentResolver().insert(Uri.parse(reminderUriString), reminderValues);
But the issue is that i am getting warning as:
Field requires API level 14 (current min is 8): android.provider.CalendarContract.Events#CALENDAR_ID
The issue get resolved if i changed the :
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="18" />
But i want to develop my application for
android:minSdkVersion="8"
What should i do for that, please suggest me. How should i resolve the warning? and what effect the warning can do on my app.
check programmatically the build.version and then put the code for the api level 14 inside the if condition.
so you don't have to do it in manifest xml,so you can run the code in minimum version devices.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
put the code for api level 14
}
Hello Friends Need Help!
I'm working on Android, In my application there is a requirement to set multiple reminders at a time. Something like this
for( int i = 0; i < n; i++)
{
// Code to set Reminder
}
Currently I have following code, but that works fine only for one reminder at a time.
StringTokenizer st=new StringTokenizer(strDateForReminder, "-");
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(st.nextToken()));
cal.set(Calendar.MONTH, Integer.parseInt(st.nextToken())-1);
cal.set(Calendar.YEAR, Integer.parseInt(st.nextToken()));
String strTime= textView.getText().toString().trim();
// Toast.makeText(getApplicationContext(), "strTime= "+strTime, Toast.LENGTH_LONG).show();
String[] strTimeArray = strTime.split(getResources().getString(R.string.delimiter));
String[] strFirstTime=strTimeArray[0].split(":");
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(strFirstTime[0]));
cal.set(Calendar.MINUTE, Integer.parseInt(strFirstTime[1]));
cal.set(Calendar.SECOND, 00);
Intent intent = new Intent(Intent.ACTION_EDIT);
intent.setType("vnd.android.cursor.item/event");
intent.putExtra("beginTime", cal.getTimeInMillis());
intent.putExtra("endTime", cal.getTimeInMillis()+90*60*1000);
intent.putExtra("title", "Reminder");
startActivity(intent);
Please Help. Thanks in Advance!
If I understand correctly, your approach using an activity only allows you to add one event at a time because the user has to interact with the device to confirm it. What you want is the new CalendarContract introduced in 4.0.
From Android Cookbook:
The ContentProvider-based method may be preferable if you do not want the user to have to interact with a calendaring application. In Froyo and Gingerbread and Honeycomb releases, you had to "know" the names to use for the various fields you wanted to interact with. We do not cover this method as it is officially unsupported, but you can find a good article on the web by our contributor Jim Blacker, at http://jimblackler.net/blog/?p=151.
Effective with Ice Cream Sandwich (Android 4, API level 14), the new CalendarContract class holds, in a variety of nested classes, all the constants needed to make a portable calendar application. This is shown inserting a Calendar Event directly into the user's first Calendar (using id 1); obviously there should be a drop-down listing the user's calendars in a real application.
public void addEvent(Context ctx, String title, Calendar start, Calendar end) {
Log.d(TAG, "AddUsingContentProvider.addEvent()");
TextView calendarList =
(TextView) ((Activity) ctx).findViewById(R.id.calendarList);
ContentResolver contentResolver = ctx.getContentResolver();
ContentValues calEvent = new ContentValues();
calEvent.put(CalendarContract.Events.CALENDAR_ID, 1); // XXX pick)
calEvent.put(CalendarContract.Events.TITLE, title);
calEvent.put(CalendarContract.Events.DTSTART, start.getTimeInMillis());
calEvent.put(CalendarContract.Events.DTEND, end.getTimeInMillis());
calEvent.put(CalendarContract.Events.EVENT_TIMEZONE, "Canada/Eastern");
Uri uri = contentResolver.insert(CalendarContract.Events.CONTENT_URI, calEvent);
// The returned Uri contains the content-retriever URI for
// the newly-inserted event, including its id
int id = Integer.parseInt(uri.getLastPathSegment());
Toast.makeText(ctx, "Created Calendar Event " + id,
Toast.LENGTH_SHORT).show();
}
I think what you're looking for is AlarmManager.
The code i'm working on lists the events from the calendar, i need to limit the range of dates, and in the examples i see this code:
// Construct the query with the desired date range.
Uri.Builder builder = Instances.CONTENT_URI.buildUpon();
ContentUris.appendId(builder, startMillis);
ContentUris.appendId(builder, endMillis);
I don't understand why appendId is used in this way. startMillis and endMillis are not ids, i would expect that the parameter name had to be provided eg "startdate" , It's not clear to me why this works, and what other parameters could be specified this way. Are there more parameters supported by appenedId? How can i know?
What appendId actually does is add a /# to your uri where # is a number. In your example (assuming startMillis = 1000 and endMillis = 3000 and the uri content://com.google.calendar/) this would mean your uri could end up like this:
content://com.google.calendar/1000/3000
This is something that a uri parser can pickup:
URIMatcher.addURI(AUTHORITY, calendar + "/#/#", DATE_RANGE);
Long story short: appendId is just a convenient and type-safe way to add an integer to your uri path.
I too have been trying to understand more about ContentUris as I had a section of code that wasn't working within the CalendarContract Instances table. This is strange because I didn't need to pass these in for the Calendars or Events table queries that I have developed.
So I added the appendId statements and passed in the current time in UTC for both values and the code now works. The actual query in my code is using the current time to looking for current events - please see the code below. If I take the appendID statements out an exception is raised - I think it was something like Content Provider URL not found.
String instanceQuery = "EVENT_ID = " + event_id +
" AND begin <= " + now +
" AND end >= " + now;
Uri.Builder eventsUriBuilder = CalendarContract.Instances.CONTENT_URI.buildUpon();
ContentUris.appendId(eventsUriBuilder, now);
ContentUris.appendId(eventsUriBuilder, now);
Uri eventsUri = eventsUriBuilder.build();
Cursor instanceCursor = null;
instanceCursor = ctx.getContentResolver().query(eventsUri,
new String[] { CalendarContract.Instances.EVENT_ID,
CalendarContract.Instances.BEGIN,
CalendarContract.Instances.END},
instanceQuery,
null,
null);
My code is working but I would like to know what impact the appendID statements actually have, e.g. do the values add any constraints. It looks like my actual query is overriding any implied range that is passed in and I really don't understand why they are required.
Hopefully a brief explanation from someone who understands this more would benefit the developer community....
I made this code:
long eventID = 208;
Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
Intent intent = new Intent(Intent.ACTION_VIEW)
.setData(uri);
startActivity(intent);
I made sure the EventID was correct, and the event-title showed in the view was correct.
THE PROBLEM is the event time was incorrect, like: 1970-1-1 8:00.
Why? Anyone can Help? Thanks.
You have to add the event begin & end time to intent's extra data :
intent.putExtra("beginTime", beginMilliTS);
intent.putExtra("endTime", endMilliTS);
I got this working by using the values from "begin" and "end" field of an event instance.
This should work too with "dtstart" and "dtend" field from an event.
This may help you!!!
http://developer.android.com/guide/topics/providers/calendar-provider.html
on Android 4.2.2, seems still having the same problem. Is it the correct behavior, or some thing missing here?
got the event id through Instances.query(Globals.sContext.getContentResolver(), proj, begin, end); proj= String[]{Instances.EVENT_ID, Instances.BEGIN, Instances.END...};
use the even id to view the event in calendar app.
tried with code (from http://developer.android.com/guide/topics/providers/calendar-provider.html), it still shows December 31 1969 on the 'Detail view' opened by the 'intent'; and shows current date in the 'Edit event' form if clicking on the the event on the 'Detail view' of the calendar.
...
Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
Intent intent = new Intent(Intent.ACTION_VIEW)
.setData(uri);
startActivity(intent);
and still does not work even with the:
intent.putExtra("beginTime", from);
intent.putExtra("endTime", till); //'from', 'till' is the mills got from the Instances.BEGIN/END fields from the query
EDIT:
the following code works. only difference is using the define CalendarContract.EXTRA_EVENT_BEGIN_TIME
Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
intent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, from);
intent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, till);
startActivity(intent);
What I want: I want to add calendar events in Android 2.2.
What I Have: I have added an event using the below code
Uri calendars = Uri.parse("content://com.android.calendar/events");
Cursor managedCursor = managedQuery(calendars, null, null, null, null);
startManagingCursor(managedCursor);
managedCursor.moveToFirst();
String ID = null;
do
{
ID = managedCursor.getString(managedCursor.getColumnIndexOrThrow("_id"));
}
while (managedCursor.moveToNext());
managedCursor.close();
int NewID = Integer.parseInt(ID) + 1;
ContentValues event = new ContentValues();
event.put("calendar_id", NewID); // --- Some confusion Here with the ID,
// --- not sure how to use it here
event.put("title", "New Event Title");
event.put("description", "Event Desc");
event.put("eventLocation", "Somewhere");
long startTime = System.currentTimeMillis() + 1000 * 60 * 60;
long endTime = System.currentTimeMillis() + 1000 * 60 * 60 * 2;
event.put("dtstart", startTime);
event.put("dtend", endTime);
event.put("allDay", 0); // 0 for false, 1 for true
event.put("eventStatus", 1);
event.put("visibility", 0);
event.put("transparency", 0);
event.put("hasAlarm", 0); // 0 for false, 1 for true
Uri eventsUri = Uri.parse("content://com.android.calendar/events");
Uri insertedUri = getContentResolver().insert(eventsUri, event);
What is the problem:
So far I have been successful in adding a single event on the specified date time, and apparently NewID's role is suspicious to me. When I try to add some other event, I get the returned Uri insertedUri and it shows me the newly added ID at the end of the URI. But I cant see any such event on the device. May be there is some problem in my understanding of the Calendar and events, or differences in both and their ID's. Kindly guide me what I am missing or doing wrong.
Regards,
Khawar
Most of the code is fine, you just need to know a little bit of concepts regarding calendar. Actually there is more than one calendar types in Android.
To Traverse all the calendars, Use following Uri for 2.2:
Uri calendars = Uri.parse("content://com.android.calendar"+ "/calendars");
And get the values of 'id' and 'name', you will get the idea.
NewID's role is suspicious to me
Your insertion code is fine, you just need to give the id of that calendar in which you want to insert any event.
I still believe that even myself needs to learn alot so if you have anything to tell or correct, you are most welcome. Following links helped me:
Working with Android Calendars
Accessing Calendars events without using gdata api