Як додати події календаря в Android?


159

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

Це правда, і якщо так, як я програмно додати подію до календаря користувача? Чи є спільний API, яким вони всі діляться?

Для чого це варто, ми, напевно, орієнтуємось на Android 2.x.


Напевно, ви повинні прийняти відповідь oriharel, оскільки він надає код для виконання вашого завдання.
jww

1
@SumitSharma ваше посилання, здається, більше не працює - і здається досить підозрілим у діалоговому вікні автоматичної установки.
виправлення

Відповіді:


17

як я можу програмно додати подію до календаря користувача?

Який календар?

Чи є спільний API, яким вони всі діляться?

Ні, не більше, ніж є "загальний API, яким вони всі діляться" для програм календаря Windows. Існують деякі загальні формати даних (наприклад, iCalendar) та протоколи Інтернет (наприклад, CalDAV), але немає загального API. Деякі програми календаря навіть не пропонують API.

Якщо є конкретні програми календаря, з якими ви хочете інтегруватися, зв’яжіться зі своїми розробниками та визначте, чи пропонують вони API. Так, наприклад, програма "Календар" від проекту з відкритим кодом для Android, яку цитує Майра, не пропонує документально підтверджених та підтримуваних API. Google навіть прямо заявив розробникам не використовувати методи, викладені в навчальному посібнику, цитованому Mayra.

Інший варіант полягає в тому, щоб ви додали події до відповідного інтернет-календаря. Наприклад, найкращий спосіб додавання подій до програми Calendar із проекту з відкритим кодом Android - це додавання події до Google Календар Google через відповідні API GData.


ОНОВЛЕННЯ

Додано Android 4.0 (рівень API 14) CalendarContract ContentProvider.


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

3
@ Петер Нельсон: "Ми не хочемо орієнтуватися на конкретний календар - ми просто хочемо мати можливість додавати події до будь-якого календаря, який користувач використовує, як зручність для користувача". - ви не можете робити це на Android більше, ніж це можна зробити в Windows. На жодній платформі ви не знаєте, "яким би календарем користувач не користувався", і на жодній платформі не існує універсального API для роботи з таким додатком календаря.
CommonsWare

22
Я не знаю, чому ви продовжуєте порівнювати це з Windows - Усі, кого я знаю, використовують їхній телефон для організації своїх графіків і зустрічей - Я не знаю того, хто це робить на своєму ПК - можливо, це покоління. Але я розумію, що Android не може цього зробити. Дякую.
Пітер Нельсон

5
@ Петер Нельсон: Я продовжую порівнювати це з Windows, тому що люди роблять однакові припущення. Багато розробників думають, що вони можуть "додавати події до будь-якого календаря, який користувач використовує" в Windows, тому що вони думають, що всі використовують Outlook, а значить, є лише один "будь-який календар".
CommonsWare

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?
Шрікант Пай

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

4
Повний підручник тут: code.tutsplus.com/tutorials/… Краще використовувати константи, щоб уникнути помилок;)
Адрієн Кадет

7
Ваш код повідомляє вашому додатку надсилати дані в інше (календарне) додаток, яке потім використовує ці дані для додавання нових подій календаря. Ваш додаток не записує та не читає дані календаря, тому вам не потрібні дозволи в маніфесті.
Співав

66

Використовуйте цей API у своєму коді. Він допоможе u вставити подію, подію з нагадуванням та подію із зустріччю можна ввімкнути ... Цей api працює для платформи 2.1 і вище Тим, хто використовує менше 2,1 замість вмісту: // com .android.calendar / події використовують вміст: // календар / події

 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
urvi joshi

1
значення.put (CalendarContract.Reminders.CALENDAR_ID, 1); values.put (CalendarContract.Reminders.TITLE, "Rutine Everyday1"); values.put (CalendarContract.Reminders.DTSTART, мілісекундиTimesEveryday); значення.put (CalendarContract.Reminders.HAS_ALARM, вірно); values.put ("rrule", "FREQ = DAILY"); // UNTIL = 1924885800000 значень.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 хв. і як я можу отримати ідентифікатор нагадування? Дякую
користувач1796624

Привіт, мені було цікаво, чи можливо змінити екран, на якому відображаються редаговані поля календаря (наприклад, змінити, як виглядають деякі з переглядів)?
Yulric Sequeira

@ user1950599 Однозначно ні. Намір запускає Діяльність з іншої програми, і єдиною взаємодією з нею є дані, які ви надсилаєте через наміри.
Pijusn

40

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


4
Дійсно корисний коментар, не можу
наголосити на

1
Можливо, ви можете надати якийсь код, який буде відповідати лише відповіді на посилання?
jww

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.