I created a new calendar on android and added events.
After first sync or after a few seconds it's erasing. Can somebody help with this problem?
Code:
private void createCalendar(Context context, String accName) {
Uri calUri = CalendarContract.Calendars.CONTENT_URI;
final ContentValues v = new ContentValues();
v.put(CalendarContract.Calendars.ACCOUNT_NAME, accName);
v.put(CalendarContract.Calendars.NAME, CALENDAR_NAME);
v.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CALENDAR_NAME);
v.put(CalendarContract.Calendars.ACCOUNT_TYPE, "com.google");
v.put(CalendarContract.Calendars.CALENDAR_COLOR, 0xEA8561);
v.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER);
v.put(CalendarContract.Calendars.OWNER_ACCOUNT, accName);
v.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
v.put(CalendarContract.Calendars.VISIBLE, 1);
calUri = calUri.buildUpon()
.appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, accName)
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, "com.google")
.build();
calUri = calUri.buildUpon().build();
final Uri result = context.getContentResolver().insert(calUri, v);
}
Unfortinately this is a known issue with the calendar API. you have only one option if you want to use the Android calendar- create the calendar as a local one and synchronize it yourself.
Related
I'm trying to create a calendar on google account, I managed to create calendars but none syncs with google and I don't know what I'm doing wrong.
I know where the problem more or less but I can't fix it.
The code I use is this:
public static long createCalendar (Activity activity, String name, String account, boolean local){
String color = "blue";
ContentValues calendarvalues = new ContentValues();
//The account that was used to sync the entry to the device. If the account_type is not {#link #ACCOUNT_TYPE_LOCAL} then the name and
// type must match an account on the device or the calendar will be deleted.
if(local) {
calendarvalues.put(CalendarContract.Calendars.ACCOUNT_NAME, "DUMMYLOCAL");
calendarvalues.put(CalendarContract.Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL);
}else{
calendarvalues.put(CalendarContract.Calendars.ACCOUNT_NAME, account);
calendarvalues.put(CalendarContract.Calendars.ACCOUNT_TYPE, account);
}
//Local CalendarContract.ACCOUNT_TYPE_LOCAL
calendarvalues.put(CalendarContract.Calendars.NAME, name);
calendarvalues.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, name);
calendarvalues.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.parseColor(color));
calendarvalues.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER);
// //None CalendarContract.Calendars.CAL_ACCESS_NONE Cannot access the calendar
// //freeBusy CalendarContract.Calendars.CAL_ACCESS_FREEBUSY Can only see free/busy information about the calendar
// //Read CalendarContract.Calendars.CAL_ACCESS_READ Can read all event details
// //Respond CalendarContract.Calendars.CAL_ACCESS_RESPOND Can reply yes/no/maybe to an event
// //Override CalendarContract.Calendars.CAL_ACCESS_OVERRIDE not used
// //Contributor CalendarContract.Calendars.CAL_ACCESS_CONTRIBUTOR Full access to modify the calendar, but not the access control settings
// //Editor CalendarContract.Calendars.CAL_ACCESS_EDITOR Full access to modify the calendar, but not the access control settings
// //Owner CalendarContract.Calendars.CAL_ACCESS_OWNER Full access to the calendar
// //Root CalendarContract.Calendars.CAL_ACCESS_ROOT Domain admin
calendarvalues.put(CalendarContract.Calendars.OWNER_ACCOUNT, account);
calendarvalues.put(CalendarContract.Calendars.VISIBLE, 1);
calendarvalues.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
// calendarvalues.put(CalendarContract.Calendars.CALENDAR_LOCATION, "Spain");
Uri calUri = null;
Uri result = null;
if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
PermissionUtil.requestCalendarPermission(activity);
return -1;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
calUri = CalendarContract.Calendars.CONTENT_URI;
}else{
calUri = Uri.parse("content://com.android.calendar/calendars");
}
if(calUri != null) {
if(local) {
calUri = calUri.buildUpon()
.appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, "DUMMYLOCAL")
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL)
.build();
}else {
calUri = calUri.buildUpon()
.appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, account)
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, account)
.build();
}
result = activity.getContentResolver().insert(calUri, calendarvalues);
}
if (result != null) {
try {
return Long.parseLong(result.getLastPathSegment());
} catch (Exception e) {
return -1;
}
}
return -1;
}
I think the mistake is in this line :
calendarvalues.put(CalendarContract.Calendars.ACCOUNT_TYPE, account);
because I have seen the values returned by the following query:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
calUri = CalendarContract.Calendars.CONTENT_URI;
}else{
calUri = Uri.parse(calendarUriString);
}
String[] projection = new String[]{
CalendarContract.Calendars._ID,
CalendarContract.Calendars.NAME,
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL,
CalendarContract.Calendars.ACCOUNT_NAME,
CalendarContract.Calendars.ACCOUNT_TYPE,
// CalendarContract.Calendars.CALENDAR_COLOR,
CalendarContract.Calendars.OWNER_ACCOUNT,
CalendarContract.Calendars.VISIBLE,
CalendarContract.Calendars.SYNC_EVENTS,
};
Cursor cursor = activity.getContentResolver().query(calUri, projection, null, null, null);
and the results are as follows:
id: 1
Name: My Calendar#Local
Display name: My Calendar
access level: 700
AccountName: My Calendar#Local
AccountType: com.local
ownerAccount: Owner Account visible: 1
sync: 1
id: 2
Name: test#gmail.com
Display name: test#gmail.com
access level: 700
AccountName: test#gmail.com
AccountType: com.google
ownerAccount: test#gmail.com
visible: 1
sync: 1
id: 3
Name: Test Cal
Display name: Test Cal
access level: 700
AccountName: test#gmail.com
AccountType: test#gmail.com
ownerAccount: 1
visible: 1
sync: 1
I tried to put the following:
calendarvalues.put(CalendarContract.Calendars.ACCOUNT_TYPE, "com.google");
but the calendar is not created.
If anyone knows how to do it or have any examples or documentation that may be useful, it would be helpful.
Thanks in advance.
I was struggling with the same Problem - I ended up creating a calendar using the Google Calendar API insert function. With the Quickstart Guide you should be able to create a Calendar.
Use the MakeRequestTask#mService like this:
Calendar newCalendar = new Calendar();
newCalendar.setSummary("Calendar Name");
newCalendar.setTimeZone(TIME_ZONE); //assuming you have it as a constant somewhere
String newCalendarId = null;
try {
com.google.api.services.calendar.model.Calendar insertedCalendar = mService.calendars().insert(newCalendar).execute();
newCalendarId = insertedCalendar.getId();
} catch(Exception ignore){}
and then force an account sync with
Bundle extras = new Bundle();
extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
ContentResolver.requestSync(selectedAccount, CalendarContract.AUTHORITY, extras);
I'm trying to create calendar by using code from this topic
private static void createCalendar( Context mContext, Account account)
{
final ContentValues v = new ContentValues();
v.put(CalendarContract.Calendars.NAME,"TEST");
v.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "TEST");
v.put(CalendarContract.Calendars.ACCOUNT_NAME, account.name);
v.put(CalendarContract.Calendars.ACCOUNT_TYPE, account.type);
v.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.GREEN);
v.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER);
v.put(CalendarContract.Calendars.OWNER_ACCOUNT, account.name);
// v.put(CalendarContract.Calendars._ID, 123);
v.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
v.put(CalendarContract.Calendars.VISIBLE, 1);
Uri creationUri = asSyncAdapter(CalendarContract.Calendars.CONTENT_URI, account.name, account.type);
Uri calendarData = mContext.getContentResolver().insert(creationUri, v);
long id = Long.parseLong(calendarData.getLastPathSegment());
}
private static Uri asSyncAdapter(Uri uri, String account, String accountType)
{
return uri.buildUpon().appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true").appendQueryParameter
(CalendarContract.Calendars.ACCOUNT_NAME,account)
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, accountType) .build();
}
and then make a call:
createCalendar(c, AccountManager.get(c).getAccountsByType("com.google")[0]); // i've checked - it's correct account to add calendar
Then i retrive data from ContentResolver
final ContentResolver cr = ctx.getContentResolver();
Cursor cursor ;
cursor = cr.query(Uri.parse("content://com.android.calendar/calendars"),null, null, null, null);
and see new calendar in cursor. But:
it not appears in google accound
it removes after some time (guess, because of synchronization)
tested on 5.1.1
How can I create calendar to my account progrommatically?
Try using calendar.insert to create another calendar.
Since you're using Java, I think this code snippet might be of help:
import com.google.api.services.calendar.Calendar;
// ...
// Initialize Calendar service with valid OAuth credentials
Calendar service = new Calendar.Builder(httpTransport, jsonFactory, credentials)
.setApplicationName("applicationName").build();
// Create a new calendar
com.google.api.services.calendar.model.Calendar calendar = new Calendar();
calendar.setSummary("calendarSummary");
calendar.setTimeZone("America/Los_Angeles");
// Insert the new calendar
Calendar createdCalendar = service.calendars().insert(calendar).execute();
System.out.println(createdCalendar.getId());
Give the Try-it a dry run to see if it works.
I am following this gist, to insert event into Calendar
How do I update existing Calendar Event, which i have inserted earlier using below code:
public void addToCalender() throws ParseException {
......
ContentValues event = new ContentValues();
event.put(CalendarContract.Events.CALENDAR_ID, calendarId[0]);
event.put(CalendarContract.Events.TITLE, "Event Title");
event.put(CalendarContract.Events.DESCRIPTION, "Event Description");
event.put(CalendarContract.Events.EVENT_LOCATION, "Eevnt Location");
event.put(CalendarContract.Events.DTSTART, startCalTime);
event.put(CalendarContract.Events.DTEND, endCalTime);
event.put(CalendarContract.Events.STATUS, 1);
event.put(CalendarContract.Events.HAS_ALARM, 1);
event.put(CalendarContract.Events.EVENT_TIMEZONE, timeZone.getID());
Uri insertEventUri = AddEventActivity.this.getContentResolver().insert(
eventsUri, event);
ContentValues reminders = new ContentValues();
reminders.put(Reminders.EVENT_ID,
Long.parseLong(insertEventUri.getLastPathSegment()));
reminders.put(Reminders.METHOD, Reminders.METHOD_ALERT);
reminders.put(Reminders.MINUTES, 10);
AddEventActivity.this.getContentResolver().insert(remainderUri, reminders);
}
I would like to know, How do I :
1. Remove existing event
2. Update existing event
Here is how you can modify an event. Let's say its ID is eventID:
public void updateEvent(int eventID)
{
ContentResolver cr = context.getContentResolver();
Uri eventUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID);
ContentValues event = new ContentValues();
event.put(CalendarContract.Events.TITLE, "new title");
event.put(CalendarContract.Events.DESCRIPTION, "My cool event!");
cr.update(eventUri, event, null, null);
}
To remove an event, you have two possibilities:
If you are a standard application:
Use the previous code and replace all the event.put by this one:
event.put(CalendarContract.Events.DELETED, 1);
If you are the SyncAdapter of the calendar and want a real deletion (The previous method just says that the event should be deleted and the one that follows must be used once the calendar is being synced :
public deleteEvent(Uri eventUri)
{
cr.delete(event, null, null);
}
Where eventUri is the Uri of the event obtained as shown previously from the event ID.
For all of the previous methods, if you get an exception about not being in a sync adapter, you can use this:
public static Uri asSyncAdapter(Uri uri, String account, String accountType)
{
return uri.buildUpon()
.appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, account)
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, accountType)
.build();
}
I hope this will help you.
Source: personnal code + http://developer.android.com/guide/topics/providers/calendar-provider.html
...
Outlook in fact seems to respond to the rules defined in RFC 2446
In summary you have to specify
METHOD:REQUEST and ORGANIZER:xxxxxxxx
...
Please read the original answer by Tom Carter.
I am doing backup and restore of calendars, During restore if calendar is not present in phone(but related account is present), i am creating new calendar with the following code, it has successfully inserted into db (i can see the return value of URI and id). But in calendar application it is visible for an second and disappears,i have no clue what is going wrong, i have made the visible flag with 1 on insertion but still not working.Can someone Help.
final String INT_NAME_PREFIX = "priv";
Uri calUri = CalendarContract.Calendars.CONTENT_URI
.buildUpon()
.appendQueryParameter(
CalendarContract.CALLER_IS_SYNCADAPTER, "true")
.appendQueryParameter(Calendars.ACCOUNT_NAME,
mCurrentMirrorItem.ACCOUNT_NAME)
.appendQueryParameter(Calendars.ACCOUNT_TYPE,
mCurrentMirrorItem.ACCOUNT_TYPE).build();
String dispName = mItem.CALENDAR_DISPLAY_NAME;
String intName = INT_NAME_PREFIX + dispName;
ContentValues contentValues = new ContentValues();
if (columnNames.contains(Calendars.ACCOUNT_NAME)) {
contentValues.put(CalendarContract.Calendars.ACCOUNT_NAME,
mItem.ACCOUNT_NAME);
}
if (columnNames.contains(Calendars.ACCOUNT_TYPE)) {
contentValues.put(CalendarContract.Calendars.ACCOUNT_TYPE,
mItem.ACCOUNT_TYPE);
}
if (columnNames.contains(Calendars.NAME)) {
contentValues.put(CalendarContract.Calendars.NAME, intName);
}
if (columnNames.contains(Calendars.CALENDAR_DISPLAY_NAME)) {
contentValues.put(
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
mItem.CALENDAR_DISPLAY_NAME);
}
if (columnNames.contains(Calendars.CALENDAR_COLOR)) {
contentValues.put(CalendarContract.Calendars.CALENDAR_COLOR,
mItem.CALENDAR_COLOR);
}
if (columnNames.contains(Calendars.CALENDAR_ACCESS_LEVEL)) {
contentValues.put(
CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL,
Calendars.CAL_ACCESS_OWNER);
}
if (columnNames.contains(Calendars.OWNER_ACCOUNT)) {
contentValues.put(CalendarContract.Calendars.OWNER_ACCOUNT,
mItem.ACCOUNT_NAME);
}
if (columnNames.contains(Calendars.VISIBLE)) {
contentValues.put(CalendarContract.Calendars.VISIBLE, 1);
}
if (columnNames.contains(Calendars.SYNC_EVENTS)) {
contentValues.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
}
returnUri = cr.insert(calUri, contentValues);
long eventID = Long.parseLong(returnUri.getLastPathSegment());
calid = String.valueOf(eventID);
Log.d(tag,"calendar name: "+mItem.CALENDAR_DISPLAY_NAME+"\tNew calendar id is: "+calid+"\nInserted URI: "+returnUri);
I'm using the new Calendar API and I want to create a local calendar in my application on which the user can add custom events related to the app .. So I've been able to create it through this code:
/** Creates the values the new calendar will have */
private static ContentValues buildNewCalContentValues() {
final ContentValues cv = new ContentValues();
cv.put(Calendars.ACCOUNT_NAME, ACCOUNT_NAME);
cv.put(Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL);
cv.put(Calendars.NAME, CALENDAR_NAME);
cv.put(Calendars.CALENDAR_DISPLAY_NAME, CALENDAR_NAME);
cv.put(Calendars.CALENDAR_COLOR, 0xEA8561);
// user can only read the calendar
cv.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_READ);
cv.put(Calendars.OWNER_ACCOUNT, ACCOUNT_NAME);
cv.put(Calendars.VISIBLE, 1);
cv.put(Calendars.SYNC_EVENTS, 1);
return cv;
}
//Create and insert new calendar into android database
public static void createCalendar(Context ctx) {
ContentResolver cr = ctx.getContentResolver();
final ContentValues cv = buildNewCalContentValues();
Uri calUri = buildCalUri();
// insert the calendar into the database
cr.insert(calUri, cv);
}
But the problem is I don't know how to display it and make the user interact with it.
Any help? Thanks in advance :)