Как добавить календарь событий в Android?


160

Я только начинаю набирать скорость на Android, и сегодня на совещании по проекту кто-то сказал, что у Android нет собственного приложения-календаря, поэтому пользователи просто используют любое приложение-календарь, которое им нравится.

Это правда, и если да, то как программно добавить событие в календарь пользователя? Есть ли у них общий API?

Что бы это ни стоило, мы, вероятно, нацелены на Android 2.x.


Вам, вероятно, следует принять ответ Орихарела, поскольку он предоставляет код для выполнения вашей задачи.
17

1
@SumitSharma Ваша ссылка, похоже, больше не работает - и кажется довольно подозрительной в диалоге автоматической установки.
исправить

Ответы:


17

как программно добавить событие в календарь пользователя?

Какой календарь?

Есть ли у них общий API?

Нет, не более, чем существует «общий API, который они все используют» для приложений календаря Windows. Существует несколько распространенных форматов данных (например, iCalendar) и интернет-протоколов (например, CalDAV), но нет общего API. Некоторые приложения календаря даже не предлагают API.

Если есть определенные приложения календаря, с которыми вы хотите интегрироваться, свяжитесь с их разработчиками и определите, предлагают ли они API. Так, например, приложение Calendar из проекта Android с открытым исходным кодом, которое цитирует Mayra, не предлагает никаких документированных и поддерживаемых API. Google даже прямо сказал разработчикам, чтобы они не использовали методы, описанные в уроке, который цитирует Майра.

Другой вариант - добавить события в соответствующий интернет-календарь. Например, лучший способ добавить события в приложение «Календарь» из проекта Android с открытым исходным кодом - добавить событие в пользовательский Календарь Google через соответствующие API-интерфейсы GData.


ОБНОВИТЬ

Android 4.0 (уровень API 14) добавил а CalendarContract ContentProvider.


7
Мы не хотим настраивать таргетинг на определенный календарь - мы просто хотим иметь возможность добавлять события в любой календарь, который использует пользователь, просто для удобства пользователя. Наше приложение предоставляет интерфейс для веб-сайта, который организует профессиональные встречи и конференции. Так что, если кто-то подписывается на один, было бы неплохо добавить его в свой календарь.
Питер Нельсон

3
@ Питер Нельсон: «Мы не хотим ориентироваться на конкретный календарь - мы просто хотим иметь возможность добавлять события в любой календарь, который использует пользователь, просто для удобства пользователя». - вы не можете сделать это на Android больше, чем на Windows. Ни на одной из платформ вы не знаете, «какой календарь использует пользователь», и ни на одной платформе не существует универсального API для работы с таким приложением-календарем.
CommonsWare

22
Я не знаю, почему вы продолжаете сравнивать его с Windows - все, кого я знаю, используют свой телефон для организации своих расписаний и встреч - я не знаю никого, кто делает это на своем ПК - возможно, это дело поколений. Но я понимаю, что Android не может этого сделать. Спасибо.
Питер Нельсон

5
@ Питер Нельсон: Я продолжаю сравнивать его с Windows, потому что люди делают одни и те же предположения. Многие разработчики считают, что они могут «добавлять события в любой календарь, который использует пользователь» в Windows, потому что они думают, что все используют Outlook, и, следовательно, существует только один «любой календарь».
CommonsWare

1
@ Яр: «Основной календарь телефонов 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?
Срикант Пай

13
Вы должны использовать .setData (CalendarContract.Events.CONTENT_URI) вместо setType, потому что с setType (string) он будет падать на некоторых устройствах!
Informatic0re

4
Полное руководство здесь: code.tutsplus.com/tutorials/… Лучше использовать константы, чтобы избежать опечаток;)
Adrien Cadet

7
Ваш код говорит вашему приложению отправить данные другому (календарному) приложению, которое затем использует эти данные для добавления нового события календаря. Ваше приложение не пишет и не читает данные календаря, поэтому вам не нужны никакие разрешения в манифесте.
Поет

66

Используйте этот API в своем коде. Это поможет вам вставить событие, событие с напоминанием и событие с встречей можно включить ... Этот API работает для платформы 2.1 и выше. Те, кто использует менее 2.1 вместо контента: // com .android.calendar / events использовать контент: // 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)это работает хорошо
validcat

1
Возможно получить ошибку часового пояса. Я добавляю это и его работы eventValues.put ("eventTimezone", TimeZone.getDefault (). GetID ());
Cüneyt

2
Я android.database.sqlite.SQLiteExceptionUri reminderUri = curActivity.getApplicationContext().getContentResolver().insert(Uri.parse(reminderUriString), reminderValues);
добираюсь до

1
но один, когда я устанавливаю values.put ("rrule", "FREQ = DAILY"); и установите endDate, он не работает. событие устанавливается на все дни не до даты окончания. @AmitabhaBiswas
Урви Джоши

1
values.put (CalendarContract.Reminders.CALENDAR_ID, 1); values.put (CalendarContract.Reminders.TITLE, "Routine Everyday1"); values.put (CalendarContract.Reminders.DTSTART, millisecondsTimesEveryday); values.put (CalendarContract.Reminders.HAS_ALARM, true); values.put ("rrule", "FREQ = DAILY"); // UNTIL = 1924885800000 values.put (CalendarContract.Reminders.DTEND, EndtimeInMilliseconds); @AmitabhaBiswas
Урви Джоши

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 минут и как я могу получить идентификатор напоминания? Спасибо
user1796624

Привет, мне было интересно, возможно ли изменить экран, отображающий редактируемые поля календаря (например, изменить вид некоторых представлений)?
Юлрик Секейра

@ user1950599 Определенно нет. Intent запускает Activity из другого приложения, и единственное взаимодействие с ним - это данные, которые вы отправляете через намерение.
Пиюсн

40

Начиная с версии Android 4.0 официальные API и намерения доступны для взаимодействия с доступными поставщиками календаря .


4
Действительно полезный комментарий, не могу
подчеркнуть

1
Возможно, вы можете предоставить какой-то код, чтобы согласиться с ответом только по ссылке?
17

8

На всякий случай, если кому-то это нужно для Xamarin в c #:

        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

Календарь Google является "родным" приложением календаря. Насколько я знаю, все телефоны поставляются с установленной версией, а SDK по умолчанию предоставляет версию.

Вы можете проверить этот учебник для работы с ним.


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

если у вас есть заданная строка даты с датой и временем.

например 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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.