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


159

我只是在跟上Android的发展步伐,今天在一个项目会议上,有人说Android没有本地日历应用程序,因此用户可以使用他们喜欢的任何日历应用程序。

这是真的吗?如果是,该如何以编程方式将事件添加到用户的日历中?它们共享一个通用的API吗?

对于它的价值,我们可能针对的是Android2.x。


您可能应该接受oriharel的回答,因为他提供了完成任务的代码。
jww

1
@SumitSharma您的链接似乎不再起作用-似乎对自动安装对话框很有怀疑。
修复

Answers:


17

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

哪个日历?

它们共享一个通用的API吗?

不,只不过Windows日历应用程序有一个“它们都共享的通用API”。有一些通用的数据格式(例如,iCalendar)和Internet协议(例如,CalDAV),但是没有通用的API。某些日历应用甚至不提供API。

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

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


更新

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


6
我们不想针对特定的日历-我们只是希望能够将事件添加到用户正在使用的任何日历中,以方便用户。我们的应用程序提供了到组织专业会议的网站的界面。因此,如果有人签约,最好将其放入日历中。
彼得·纳尔逊

3
@Peter Nelson:“我们不想针对特定的日历-我们只是希望能够将事件添加到用户正在使用的任何日历中,以方便用户。” -您在Android上所做的比在Windows上所做的更多。在这两个平台上,您都不知道“用户正在使用的日历”,在这两个平台上,都没有用于处理此类日历应用程序的通用API。
CommonsWare 2010年

22
我不知道您为什么要继续将其与Windows进行比较-我认识的每个人都使用他们的电话来组织他们的日程安排和约会-我不知道有人在其PC上进行此操作-也许这是世代相传的事情。但我知道Android无法做到这一点。谢谢。
彼得·纳尔逊

5
@Peter Nelson:我一直将它与Windows进行比较,因为人们做出了相同的假设。许多开发人员认为他们可以在Windows上“将事件添加到用户正在使用的日历中”,因为他们认为每个人都使用Outlook,因此只有一个“任何日历”。
CommonsWare 2010年

1
@Yar:“任何Android手机都有的主要Android手机日历。” -除所有没有该应用程序的Android设备外。例如,许多HTC设备没有该应用程序,而是拥有自己的日历应用程序,例如左侧六英寸的HTC DROID Incredible。欢迎设备制造商以自己的实现方式替换日历应用程序-或几乎任何其他应用程序。
CommonsWare,

290

在您的代码中尝试以下操作:

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

6
我非常喜欢这种解决方案。主要是因为它促使用户选择自己的日历(如果他有多个日历)。
塞巴斯蒂安·罗斯

2
如何使它与android 2.2兼容?
Srikanth Pai 2012年

13
您应该使用.setData(CalendarContract.Events.CONTENT_URI)而不是setType,因为使用setType(string)它将在某些设备上崩溃!
Informatic0re

4
完整的教程在这里:code.tutsplus.com/tutorials/… 最好使用常量来避免错别字;)
Adrien Cadet

7
您的代码告诉您的应用将数据发送到另一个(日历)应用,然后该应用使用该数据添加新的日历事件。您的应用程序既不写入也不读取日历数据,因此您不需要清单中的任何权限。
2015年

66

在您的代码中使用此API。.它将帮助您插入事件,带有提醒的事件和与会议相关的事件...此api适用于2.1或更高版本的平台那些使用2.1以下版本而不是content:// com的人群.android.calendar / events使用content:// calendar / 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;

}

4
我添加event.put("eventTimezone", "UTC/GMT +2:00")并消除了event.put("visibility", 3)event.put("transparency", 0)它,并且效果很好
猫猫

1
可能会得到时区错误。我添加了它及其工作eventValues.put(“ eventTimezone”,TimeZone.getDefault()。getID());
库尼埃特2015年

2
我正在android.database.sqlite.SQLiteException排队Uri reminderUri = curActivity.getApplicationContext().getContentResolver().insert(Uri.parse(reminderUriString), reminderValues);
Sibidharan

1
但是当我设置values.put(“ rrule”,“ FREQ = DAILY”);时 并设置endDate,它不起作用。事件设置为整天,直到结束日期。@AmitabhaBiswas
urvi joshi

1
values.put(CalendarContract.Reminders.CALENDAR_ID,1); values.put(CalendarContract.Reminders.TITLE,“例行日常1”); values.put(CalendarContract.Reminders.DTSTART,毫秒时间每天); values.put(CalendarContract.Reminders.HAS_ALARM,true); values.put(“ rrule”,“ FREQ = DAILY”); // UNTIL = 1924885800000 values.put(CalendarContract.Reminders.DTEND,EndtimeInMilliseconds); @AmitabhaBiswas
urvi joshi

57

我使用下面的代码,它解决了我的问题,即在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);
        }

希望这会有所帮助.....


关于Build.VERSION.SDK_INT> 14,如何添加60分钟的默认提醒以及如何获取提醒的ID?谢谢
user1796624

嗨,我想知道是否可以修改显示可编辑日历字段的屏幕(例如更改某些视图的外观)?
2013年

@ user1950599绝对不是。意图从另一个应用程序启动活动,并且与活动的唯一交互是您通过该意图发送的数据。
Pijusn


8

以防万一有人在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;
    }


7

试试这个 ,

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

4

如果您具有给定的Date字符串以及date和time。

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

3

您必须添加标志:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

否则您将导致以下错误:

startActivity() 从活动上下文外部需要 FLAG_ACTIVITY_NEW_TASK

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.