Как добавить календарь событий в 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.

CommonsWare
источник
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);
oriharel
источник
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 и намерения доступны для взаимодействия с доступными поставщиками календаря .

tobsen
источник
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;
    }
Dotsa
источник
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);
Arun
источник
3

Вы должны добавить флаг:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

или вы вызовете ошибку с:

startActivity() извне контекста действия требуется FLAG_ACTIVITY_NEW_TASK

Джон Вуонг
источник