如何在 Android 中添加日历事件?

我正在了解 Android 的最新情况,今天在一个项目会议上,有人说 Android 没有本地日历应用程序,所以用户可以使用任何他们喜欢的日历应用程序。

是这样吗? 如果是这样,我如何通过编程将事件添加到用户的日历中?它们是否共享一个通用的 API?

无论如何,我们的目标可能是 Android 2.x。

218926 次浏览

谷歌日历是“本地”日历应用程序。据我所知,所有的手机都安装了一个版本,默认的 SDK 提供了一个版本。

你可以看看这个 教程的工作与它。

如何以编程方式向用户日历添加事件?

哪个日历?

它们是否共享一个通用的 API?

不,不会比 Windows 日历应用程序有一个“所有人共享的通用 API”更多。有一些通用的数据格式(如 iCalendar)和 Internet 协议(如 CalDAV) ,但没有通用的 API。有些日历应用程序甚至不提供 API。

如果您希望集成特定的日历应用程序,请与其开发人员联系,并确定他们是否提供 API。因此,例如,Mayra 引用的 Android 开源项目中的 Calendar 应用程序就没有提供文档化和支持的 API。谷歌甚至在 Mayra 引用的教程中概述了 明确地告诉开发人员不要使用这些技术

另一种选择是向有问题的 Internet 日历中添加事件。例如,从 Android 开源项目向 Calendar 应用程序添加事件的最佳方法是通过适当的 GData API 将事件添加到用户的 Google Calendar。


更新

Android 4.0(API 级别14)添加了 CalendarContract ContentProvider

在代码中尝试这样做:

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);

从 Android 版本4.0开始,官方 API 和意图是可用的与可用的 日历供应商进行交互。

在代码中使用此 API。.它将帮助您插入事件,事件与提醒和事件与会议可以启用... 这个 API 的工作平台2.1及以上 那些使用少于2.1而不是 content://com.android.endar/events 的用户使用 content://endar/events

 public static long pushAppointmentsToCalender(Activity curActivity, String title, String addInfo, String place, int status, long startDate, boolean needReminder, boolean needMailService) {
/***************** Event: note(without alert) *******************/


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", title);
eventValues.put("description", addInfo);
eventValues.put("eventLocation", place);


long endDate = startDate + 1000 * 60 * 60; // For next 1hr


eventValues.put("dtstart", startDate);
eventValues.put("dtend", endDate);


// 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", status); // This information is
// sufficient for most
// entries tentative (0),
// confirmed (1) or canceled
// (2):
eventValues.put("eventTimezone", "UTC/GMT +2:00");
/*Comment below visibility and transparency  column to avoid java.lang.IllegalArgumentException column visibility is invalid error */


/*eventValues.put("visibility", 3); // visibility to default (0),
// confidential (1), private
// (2), or public (3):
eventValues.put("transparency", 0); // You can control whether
// an event consumes time
// opaque (0) or transparent
// (1).
*/
eventValues.put("hasAlarm", 1); // 0 for false, 1 for true


Uri eventUri = curActivity.getApplicationContext().getContentResolver().insert(Uri.parse(eventUriString), eventValues);
long eventID = Long.parseLong(eventUri.getLastPathSegment());


if (needReminder) {
/***************** Event: Reminder(with alert) Adding reminder to event *******************/


String reminderUriString = "content://com.android.calendar/reminders";


ContentValues reminderValues = new ContentValues();


reminderValues.put("event_id", eventID);
reminderValues.put("minutes", 5); // Default value of the
// system. Minutes is a
// integer
reminderValues.put("method", 1); // Alert Methods: Default(0),
// Alert(1), Email(2),
// SMS(3)


Uri reminderUri = curActivity.getApplicationContext().getContentResolver().insert(Uri.parse(reminderUriString), reminderValues);
}


/***************** Event: Meeting(without alert) Adding Attendies to the meeting *******************/


if (needMailService) {
String attendeuesesUriString = "content://com.android.calendar/attendees";


/********
* To add multiple attendees need to insert ContentValues multiple
* times
***********/
ContentValues attendeesValues = new ContentValues();


attendeesValues.put("event_id", eventID);
attendeesValues.put("attendeeName", "xxxxx"); // Attendees name
attendeesValues.put("attendeeEmail", "yyyy@gmail.com");// Attendee
// E
// mail
// id
attendeesValues.put("attendeeRelationship", 0); // Relationship_Attendee(1),
// Relationship_None(0),
// Organizer(2),
// Performer(3),
// Speaker(4)
attendeesValues.put("attendeeType", 0); // None(0), Optional(1),
// Required(2), Resource(3)
attendeesValues.put("attendeeStatus", 0); // NOne(0), Accepted(1),
// Decline(2),
// Invited(3),
// Tentative(4)


Uri attendeuesesUri = curActivity.getApplicationContext().getContentResolver().insert(Uri.parse(attendeuesesUriString), attendeesValues);
}


return eventID;


}

我使用下面的代码,它解决了我的问题,添加事件在 ICS 的默认设备日历,也在版本较少的 ICS

    if (Build.VERSION.SDK_INT >= 14) {
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);
}


else {
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);
}

希望能有所帮助。

试试这个,

   Calendar beginTime = Calendar.getInstance();
beginTime.set(yearInt, monthInt - 1, dayInt, 7, 30);






ContentValues l_event = new ContentValues();
l_event.put("calendar_id", CalIds[0]);
l_event.put("title", "event");
l_event.put("description",  "This is test event");
l_event.put("eventLocation", "School");
l_event.put("dtstart", beginTime.getTimeInMillis());
l_event.put("dtend", beginTime.getTimeInMillis());
l_event.put("allDay", 0);
l_event.put("rrule", "FREQ=YEARLY");
// status: 0~ tentative; 1~ confirmed; 2~ canceled
// l_event.put("eventStatus", 1);


l_event.put("eventTimezone", "India");
Uri l_eventUri;
if (Build.VERSION.SDK_INT >= 8) {
l_eventUri = Uri.parse("content://com.android.calendar/events");
} else {
l_eventUri = Uri.parse("content://calendar/events");
}
Uri l_uri = MainActivity.this.getContentResolver()
.insert(l_eventUri, l_event);

如果给定的 Date 字符串包含日期和时间。

例如 String givenDateString = pojoModel.getDate()/* Format dd-MMM-yyyy hh:mm:ss */

使用以下代码向日历中添加具有日期和时间的事件

Calendar cal = Calendar.getInstance();
cal.setTime(new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss").parse(givenDateString));
Intent intent = new Intent(Intent.ACTION_EDIT);
intent.setType("vnd.android.cursor.item/event");
intent.putExtra("beginTime", cal.getTimeInMillis());
intent.putExtra("allDay", false);
intent.putExtra("rrule", "FREQ=YEARLY");
intent.putExtra("endTime",cal.getTimeInMillis() + 60 * 60 * 1000);
intent.putExtra("title", " Test Title");
startActivity(intent);

以防万一有人需要这个用于 c # 中的 Xamarin:

        Intent intent = new Intent(Intent.ActionInsert);
intent.SetData(Android.Provider.CalendarContract.Events.ContentUri);
intent.PutExtra(Android.Provider.CalendarContract.ExtraEventBeginTime, Utils.Tools.CurrentTimeMillis(game.Date));
intent.PutExtra(Android.Provider.CalendarContract.EventsColumns.AllDay, false);
intent.PutExtra(Android.Provider.CalendarContract.EventsColumns.EventLocation, "Location");
intent.PutExtra(Android.Provider.CalendarContract.EventsColumns.Description, "Description");
intent.PutExtra(Android.Provider.CalendarContract.ExtraEventEndTime, Utils.Tools.CurrentTimeMillis(game.Date.AddHours(2)));
intent.PutExtra(Android.Provider.CalendarContract.EventsColumns.Title, "Title");
StartActivity(intent);

助手职能:

    private static readonly DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);


public static long CurrentTimeMillis(DateTime date)
{
return (long)(date.ToUniversalTime() - Jan1st1970).TotalMilliseconds;
}

你必须加上一个标志:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

否则,你会造成错误:

来自活动上下文外部的 startActivity()需要 FLAG_ACTIVITY_NEW_TASK

下面是在日历中添加事件的 Kotlin 版本:

            val intent = Intent(Intent.ACTION_EDIT)
intent.type = "vnd.android.cursor.item/event"
intent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, startTime)
intent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime)
intent.putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, false)
intent.putExtra(CalendarContract.Events.TITLE, mTitle)
startActivity(intent)

Android 主要提供了两种处理日历事件的方法。一个是使用 Calendar Provider,另一个是把它交给 system Calendar app.

Calendar Provider 为我们提供了所有功能,包括插入、查询、更新和删除现有日历事件。但是,这些步骤非常繁琐,必须要求用户的运行时权限(android.permission.READ_CALENDAR 和 android.permission.WRITE_CALENDAR)才能读写敏感的日历信息。这种方法很容易出错。

enter image description here

谷歌官方建议开发者使用第二种方法,即通过使用意图将所有日历操作移交给系统日历应用程序。日历应用程序是打开后,我们的应用程序要求的权利

甚至插入新的日历

    val startMillis: Long = Calendar.getInstance().run {
set(2012, 0, 19, 7, 30)
timeInMillis
}
val endMillis: Long = Calendar.getInstance().run {
set(2012, 0, 19, 8, 30)
timeInMillis
}
val intent = Intent(Intent.ACTION_INSERT)
.setData(CalendarContract.Events.CONTENT_URI)
.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, startMillis)
.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endMillis)
.putExtra(CalendarContract.Events.TITLE, "Yoga")
.putExtra(CalendarContract.Events.DESCRIPTION, "Group class")
.putExtra(CalendarContract.Events.EVENT_LOCATION, "The gym")
.putExtra(CalendarContract.Events.AVAILABILITY, CalendarContract.Events.AVAILABILITY_BUSY)
.putExtra(Intent.EXTRA_EMAIL, "rowan@example.com,trevor@example.com")
startActivity(intent)

下面的活动是开放的

enter image description here