I have added a calendar event programatically using the caledarcontract api and obtained a eventId. Similarly i added a reminder for this event and saved the reminderId too. Now i dont want a reminder for this event(or i would like to turn off the reminder), so i am trying to delete the reminder using the reminderId but i am not able to delete. I tried to delete the reminder using the eventId too but its not working.
public int AddEventToCalendar(String calendarId, Entity entity) {
// TODO Auto-generated method stub
ContentValues event = new ContentValues();
event.put("calendar_id", calendarId);
event.put("title", entity.description);
event.put("dtstart", System.currentTimeMillis());
event.put("dtend", System.currentTimeMillis() + 3600*1000);
event.put("allDay", 0);
//status: 0~ tentative; 1~ confirmed; 2~ canceled
event.put("eventStatus", 1);
//0~ default; 1~ confidential; 2~ private; 3~ public
event.put("visibility", 0);
//0~ opaque, no timing conflict is allowed; 1~ transparency, allow overlap of scheduling
event.put("transparency", 0);
//0~ false; 1~ true
event.put("hasAlarm", 1);
Uri add_eventUri;
if (Build.VERSION.SDK_INT >= 8) {
add_eventUri = Uri.parse("content://com.android.calendar/events");
} else {
add_eventUri = Uri.parse("content://calendar/events");
}
Uri l_uri = context.getContentResolver().insert(add_eventUri, event);
if(l_uri != null)
{
long eventID = Long.parseLong(l_uri.getLastPathSegment());
return (int) eventID;
}
else
return 0;
}
public int AddReminderOnEvent(Entity entity)
{
if(entity.eventId != 0)
{
ContentValues reminderValues = new ContentValues();
reminderValues.put("event_id", entity.eventId);
reminderValues.put("method", 1);// will alert the user with a reminder notification
reminderValues.put("minutes", 0);// number of minutes before the start time of the event to fire a reminder
Uri reminder_eventUri;
if (Build.VERSION.SDK_INT >= 8) {
reminder_eventUri = Uri.parse("content://com.android.calendar/reminders");
} else {
reminder_eventUri = Uri.parse("content://calendar/reminders");
}
Uri r_uri = context.getContentResolver().insert(reminder_eventUri, reminderValues);
if(r_uri != null)
{
long reminderID = Long.parseLong(r_uri.getLastPathSegment());
return (int) reminderID;
// Toast.makeText(getApplicationContext(), "Event Created Successfully", Toast.LENGTH_LONG).show();
}
else
return 0;
}
else
{
return 0;
}
}
public boolean DeleteReminderOnTask(int eventId, int reminderId) {
// TODO Auto-generated method stub
Uri delete_reminderUri;
if (Build.VERSION.SDK_INT >= 8) {
delete_reminderUri = Uri.parse("content://com.android.calendar/reminders");
} else {
delete_reminderUri = Uri.parse("content://calendar/reminders");
}
delete_reminderUri = ContentUris.withAppendedId(delete_reminderUri, reminderId);
int rows = context.getContentResolver().delete(delete_reminderUri,null , null);
if(rows > 0)
return true;
else
return false;
}
After executing this code everytime the rows returns 0 meaning that no rows have been altered. And the reminder comes up exactly at the appropriate time. How to delete the reminder from the calendar without deleting the event?
I'm not sure which SDK version you're running against when failing, but this code (which is essentially the same as yours, less the version check) works for me:
Uri reminderUri = ContentUris.withAppendedId(
CalendarContract.Reminders.CONTENT_URI, reminderId);
int rows = contentResolver.delete(reminderUri, null, null);
I got reminderId by querying the event's reminders:
String[] projection = new String[] {
CalendarContract.Reminders._ID,
CalendarContract.Reminders.METHOD,
CalendarContract.Reminders.MINUTES
};
Cursor cursor = CalendarContract.Reminders.query(
contentResolver, eventId, projection);
while (cursor.moveToNext()) {
long reminderId = cursor.getLong(0);
int method = cursor.getInt(1);
int minutes = cursor.getInt(2);
// etc.
}
cursor.close();
This might not be the only or best way, but all I could figure out was how to remove all reminders for an event. I don't know of a way to remove just one reminder.
//What we want to update
ContentValues values = new ContentValues();
values.put(Events.HAS_ALARM, 0);
//We're setting the event to have no alarms
int result = getContentResolver().update(
Events.CONTENT_URI,
values,
Events._ID + " = ?",
new String[]{"44"}
);
Unfortunately, this removes all reminders, but I'm not sure multiple reminders are really supported by Android 14+ or most calendar providers (e.g. Exchange). The calendar app in ICS only allows adding one reminder (despite saying "Add Reminders").
And if i use another application such as Business Calendar to add multiple reminders, when I check in Exchange, it only shows ones reminder. It does show multiple reminders in the calendar app but only on that device, not on other devices, so multiple reminders seem to be local only.
Related
Events are adding to calendar properly till api 22.
I have also implemented run- time permissions for Marshmallow , Calender permission is allowed in Phone setting for my application is clearly visible.
But still nothing is updating on phone calendar and also app giving no error or warning.
Below is my method to add event programatically on phone calendar.
private void addEventToCalender(Activity ourActivity, String title, String desc, String place, int status, long startDate, long endDte, boolean needReminder, boolean needMailService) {
try {
String eventUriString = "content://com.android.calendar/events";
ContentValues eventValues = new ContentValues();
eventValues.put("calendar_id", 1); // id, We need to choose from // our mobile for primary its 1
eventValues.put("title", "My Title");
eventValues.put("description","My Description" );
eventValues.put("eventLocation", "Noida,UP ";
eventValues.put("dtstart", startDate);
eventValues.put("dtend", endDte);
eventValues.put("allDay", 1); // 1 for whole day
//eventValues.put("rrule", "FREQ=YEARLY");
// 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
eventValues.put("eventStatus", 1); // This information is
// sufficient for most
// entries tentative (0),
// confirmed (1) or canceled
// (2):
eventValues.put("eventTimezone", "UTC/GMT " + Constants.tzone);
eventValues.put("hasAlarm", 1); // 0 for false, 1 for true
Uri eventUri = this.getApplicationContext().getContentResolver().insert(Uri.parse(eventUriString), eventValues);
long eventID = Long.parseLong(eventUri.getLastPathSegment());
Log.i("eventID", eventID + "");
showSnackBar("Event added to calender successfuly.");
} catch (Exception ex) {
Log.e("error", "Error in adding event on calendar" + ex.getMessage());
showSnackBar("Ünable to add event to calender!");
}
}
May be you want to use inside Fragment .
at first use :
super.requestPermissions( new String[]{Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
Inside fragment, you need to call:
FragmentCompat.requestPermissions(permissionsList, RequestCode)
Note:
ActivityCompat.requestPermissions(Activity, permissionsList, RequestCode);
add this library for FragmentCompat class in app.gradle.
compile 'com.android.support:support-v13:version_of_library'
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 making a basic Dashclock extension that polls CalendarContract.Events for a list of all calendar events synced to the user's device, retrieve the one that's scheduled to happen the soonest, and post the time, title, location, and desctiption. Here's my code:
public class FullCalService extends DashClockExtension {
public static final String[] FIELDS = { Events._ID, Events.TITLE,
Events.ALL_DAY, Events.EVENT_LOCATION, Events.DTSTART,
Events.EVENT_TIMEZONE, Events.DESCRIPTION };
public FullCalService() {
}
#Override
protected void onUpdateData(int arg0) {
TimeZone tz = TimeZone.getDefault();
long currentTimeMillis = Calendar.getInstance().getTimeInMillis() - tz.getRawOffset();
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this);
Cursor c;
if (prefs.getBoolean("allDayAllowed", false)) {
c = getContentResolver().query(
Events.CONTENT_URI,
FIELDS,
new StringBuilder().append("(").append(Events.DTSTART)
.append(" >= ?)").toString(),
new String[] { Long.toString(currentTimeMillis) },
Events.DTSTART, null);
} else {
c = getContentResolver().query(
Events.CONTENT_URI,
FIELDS,
new StringBuilder().append("((").append(Events.ALL_DAY)
.append("= ?) AND (").append(Events.DTSTART)
.append(" >= ?))").toString(),
new String[] { Integer.toString(0),
Long.toString(currentTimeMillis) }, Events.DTSTART,
null);
}
if (c.moveToFirst()) {
long eventTimeMillis = c.getLong(c.getColumnIndex(Events.DTSTART));
// if (tz.inDaylightTime(new Date(eventTimeMillis))) {
// eventTimeMillis += tz.getDSTSavings();
// }
//Log.d("DesCal service", "Value of hoursToReveal: "+prefs.getString("hoursToReveal", "1"));
if (eventTimeMillis < currentTimeMillis + 360000
* Integer.parseInt(prefs.getString("hoursToReveal", "1"))) {
String title = c.getString(c.getColumnIndex(Events.TITLE));
String loc = c.getString(c
.getColumnIndex(Events.EVENT_LOCATION));
String time = DateUtils.formatDateTime(this, eventTimeMillis,
DateUtils.FORMAT_SHOW_TIME);
String desc = c.getString(c.getColumnIndex(Events.DESCRIPTION));
StringBuilder expandedBody = new StringBuilder(time);
if (!loc.isEmpty()){
expandedBody.append(" - ").append(loc);
}
expandedBody.append("\n").append(desc);
String uri = new StringBuilder(
"content://com.android.calendar/events/").append(
c.getLong(c.getColumnIndex(Events._ID))).toString();
publishUpdate(new ExtensionData()
.visible(true)
.status(time)
.expandedTitle(title)
.expandedBody(expandedBody.toString())
.icon(R.drawable.ic_dash_cal)
.clickIntent(
new Intent(Intent.ACTION_VIEW, Uri.parse(uri))));
c.close();
} else {
publishUpdate(new ExtensionData().visible(false));
c.close();
}
} else {
publishUpdate(new ExtensionData().visible(false));
c.close();
}
}
}
Upon first install, it appeared to work just fine. However, after the event began, it would not grab any future events. Is there a reason why the extension will not refresh itself?
How are you triggering further updates? You need to manually specify when you'd like to have onUpdateData called, e.g. when there's a change to a content provider, or when the screen turns on, etc. Extensions by default refresh only every 30 minutes or so. See the source for the built in calendar extension for example code.
I have a list of events in my app. A button on the side lets the user add the event date and time to his/her calender. I use a calender intent to redirect the user to the android calender which the corresponding date and time. Now after the user adds the event to his calender, I would like to disable the 'add event' button which corresponds to the events he/she had already added(so the user avoid adding the same event again). How can I do this? I have gone through the new calender API for android 4.0 but I wasnt able to achieve what I wanted.
Basically what I want is to avoid repeated entries for the same event in the users calender.
Any help would be appreciated.
You should test, if an instance for this event exists. See the documentation of the Android's CalendarContract.Instances class.
Especially the second query method should be helpful in this case.
This examples is some code, I posted on my blog post about the CalendarContract provider - slightly altered for your needs:
long begin = // starting time in milliseconds
long end = // ending time in milliseconds
String[] proj =
new String[]{
Instances._ID,
Instances.BEGIN,
Instances.END,
Instances.EVENT_ID};
Cursor cursor =
Instances.query(getContentResolver(), proj, begin, end, "\"Your event title\"");
if (cursor.getCount() > 0) {
// deal with conflict
}
Be aware: The time is always in UTC millis since the epoch. So you might have to adjust given the user's timezone.
And the last parameter should contain the title of the event you have added to the calendar. Keep the quotes - otherwise Android looks for "your" or "event" or "title"!
And do not forget to include the necessary permissions.
Instances.query is not recommended to be run on the UI thread, but can be done efficiently by ensuring start and end time duration is minimized.
The search string will search all values, not just title, so adding a loop to check for that an exact field value is necessary.
public boolean eventExistsOnCalendar(String eventTitle, long startTimeMs, long endTimeMs) {
if (eventTitle == null || "".equals(eventTitle)) {
return false;
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
return false;
}
// If no end time, use start + 1 hour or = 1 day. Query is slow if searching a huge time range
if (endTimeMs <= 0) {
endTimeMs = startTimeMs + 1000 * 60 * 60; // + 1 hour
}
final ContentResolver resolver = mContext.getContentResolver();
final String[] duplicateProjection = {CalendarContract.Events.TITLE}; // Can change to whatever unique param you are searching for
Cursor cursor =
CalendarContract.Instances.query(
resolver,
duplicateProjection,
startTimeMs,
endTimeMs,
'"' + eventTitle + '"');
if (cursor == null) {
return false;
}
if (cursor.getCount() == 0) {
cursor.close();
return false;
}
while (cursor.moveToNext()) {
String title = cursor.getString(0);
if (eventTitle.equals(title)) {
cursor.close();
return true;
}
}
cursor.close();
return false;
}
I have used following way to check it ...what i am passing event_id to check whether is it in calendar or not....
public boolean isEventInCal(Context context, String cal_meeting_id) {
Cursor cursor = context.getContentResolver().query(
Uri.parse("content://com.android.calendar/events"),
new String[] { "_id" }, " _id = ? ",
new String[] { cal_meeting_id }, null);
if (cursor.moveToFirst()) {
//Yes Event Exist...
return true;
}
return false;
}
Please check this, this might help:
private static boolean isEventInCalendar(Context context, String titleText, long dtStart, long dtEnd) {
final String[] projection = new String[]{CalendarContract.Instances.BEGIN, CalendarContract.Instances.END, CalendarContract.Instances.TITLE};
Cursor cursor = CalendarContract.Instances.query(context.getContentResolver(), projection, dtStart, dtEnd);
return cursor != null && cursor.moveToFirst() && cursor.getString(cursor.getColumnIndex(CalendarContract.Instances.TITLE)).equalsIgnoreCase(titleText);
}
As part of a project, I created an android application which communicates with an online database (MySQL) to integrate the appointment has taken the online calendar.
I collect the data, converted to Json, but when the inscrires in the agenda of android mobile I encounter a probleme, here is my code : (sorry for my english )
EDIT :
public class calendrier extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Cursor cursor = getContentResolver()
.query(Uri.parse("content://com.android.calendar/calendars"),
new String[] { "_id", "displayName" }, "selected=1",
null, null);
if (cursor != null && cursor.moveToFirst()) {
String[] calNames = new String[cursor.getCount()];
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();
}
cursor.close();
if (calIds.length > 0) {
// we're safe here to do any further work
}
// grab calendar id from above
int cal_id = calIds[0];
// set the content value
ContentValues cv = new ContentValues();
cv.put("calendar_id", cal_id);
cv.put("title", "titre");
cv.put("description", "bla bla bla");
cv.put("eventLocation", "city");
// note: you're going to need to convert the desired date into
// milliseconds
cv.put("dtstart", System.currentTimeMillis());
cv.put("dtend", System.currentTimeMillis()
+ DateUtils.DAY_IN_MILLIS);
cv.put("allDay", 0); // true = 1, false = 0
cv.put("hasAlarm", 1);
// once desired fields are set, insert it into the table
getContentResolver().insert(
Uri.parse("content://com.android.calendar/events"), cv);
}
}
}
this code works but it asks me if I want to participate in the event when I open it and I wish he does not do
thanks
//did U include permission in your manifest.xml file
android.permission.READ_CALENDAR
android.permission.WRITE_CALENDAR
String WRITE_CALENDAR Allows an application to write (but not read) the user's calendar data.
The Uri of Calendar has changed from Android 2.2 .
Old (2.1 and before): content://calendar/
New (2.2): content://com.android.calendar/
Change your Uri to the new one.
There is no Calendar Application by default in Android. So the Uri may not work at all.
If, you are getting the first error message as "Failed to find provider info for com.android.calendar", you need to check the handset you are using to debug uses which Calendar URI.
To insert Time in Calendar event, you can use the following code example:
Calendar calendar = Calendar.getInstance();
calendar.getTimeInMillis();
cv.put("dtstart", ""+calendar.getTimeInMillis());
cv.put("dtend", ""+calendar.getTimeInMillis()+10000);