Jak dodać wydarzenia w kalendarzu na Androida?

159

Właśnie zaczynam działać na Androidzie, a dziś na spotkaniu projektowym ktoś powiedział, że Android nie ma natywnej aplikacji kalendarza, więc użytkownicy po prostu używają dowolnej aplikacji kalendarza.

Czy to prawda, a jeśli tak, jak programowo dodać wydarzenie do kalendarza użytkownika? Czy istnieje wspólny interfejs API, który wszyscy dzielą?

Jeśli chodzi o to, co jest warte, prawdopodobnie celujemy w Androida 2.x.

Peter Nelson
źródło
Prawdopodobnie powinieneś przyjąć odpowiedź oriharela, ponieważ dostarcza on kod do wykonania twojego zadania.
jww
1
@SumitSharma Twój link wydaje się już nie działać - i wydaje się dość podejrzany w oknie automatycznej instalacji.
napraw

Odpowiedzi:

17

jak programowo dodać wydarzenie do kalendarza użytkownika?

Który kalendarz?

Czy istnieje wspólny interfejs API, który wszyscy współużytkują?

Nie, nie więcej niż „wspólny interfejs API, który wszyscy współużytkują” dla aplikacji kalendarza systemu Windows. Istnieją pewne popularne formaty danych (np. ICalendar) i protokoły internetowe (np. CalDAV), ale nie ma wspólnego interfejsu API. Niektóre aplikacje kalendarza nie oferują nawet interfejsu API.

Jeśli istnieją określone aplikacje kalendarza, z którymi chcesz się zintegrować, skontaktuj się z ich programistami i określ, czy oferują one interfejs API. Na przykład aplikacja Calendar z projektu open source dla systemu Android, który przytacza Mayra, nie oferuje udokumentowanych i obsługiwanych interfejsów API. Google nawet wyraźnie powiedział programistom, aby nie używali technik przedstawionych w samouczku przytoczonym przez Mayrę.

Inną opcją jest dodanie wydarzeń do danego kalendarza internetowego. Na przykład najlepszym sposobem dodawania wydarzeń do aplikacji Kalendarz z projektu open source dla Androida jest dodanie wydarzenia do Kalendarza Google użytkownika za pośrednictwem odpowiednich interfejsów API GData.


AKTUALIZACJA

Dodano system Android 4.0 (poziom interfejsu API 14) CalendarContract ContentProvider.

CommonsWare
źródło
6
Nie chcemy kierować reklam do konkretnego kalendarza - po prostu chcemy mieć możliwość dodawania wydarzeń do dowolnego kalendarza, z którego korzysta użytkownik, tylko dla wygody użytkownika. Nasza aplikacja zapewnia interfejs do serwisu, na którym organizowane są profesjonalne spotkania i konferencje. Więc jeśli ktoś zarejestruje się na taki, byłoby miło umieścić go w swoim kalendarzu.
Peter Nelson
3
@Peter Nelson: „Nie chcemy kierować reklam na konkretny kalendarz - po prostu chcemy mieć możliwość dodawania wydarzeń do dowolnego kalendarza, z którego korzysta użytkownik, tylko dla wygody użytkownika”. - nie możesz tego zrobić na Androidzie, tak samo jak na Windowsie. Na żadnej platformie nie wiesz, "jakiego kalendarza używa użytkownik", a na żadnej z nich nie ma uniwersalnego API do pracy z taką aplikacją kalendarza.
CommonsWare
22
Nie wiem, dlaczego ciągle porównujesz to do systemu Windows - wszyscy, których znam, używają telefonu do organizowania harmonogramów i spotkań - nie znam nikogo, kto robi to na swoim komputerze - może to kwestia pokoleniowa. Ale rozumiem, że Android nie może tego zrobić. Dzięki.
Peter Nelson,
5
@Peter Nelson: Ciągle porównuję to do Windowsa, ponieważ ludzie przyjmują te same założenia. Wielu programistów uważa, że ​​mogą „dodawać wydarzenia do dowolnego kalendarza używanego przez użytkownika” w systemie Windows, ponieważ sądzą, że wszyscy używają Outlooka, a zatem istnieje tylko jeden „dowolny kalendarz”.
CommonsWare,
1
@Yar: „Główny kalendarz telefonu z systemem Android, który ma każdy telefon z systemem Android”. - z wyjątkiem wszystkich urządzeń z Androidem, które nie mają tej aplikacji. Na przykład wiele urządzeń HTC nie ma tej aplikacji, ale ma własną aplikację kalendarza, taką jak HTC DROID Incredible sześć cali po mojej lewej stronie. Producenci urządzeń mogą zastąpić aplikację kalendarza - lub prawie każdą inną aplikację - własną implementacją.
CommonsWare,
290

Spróbuj tego w swoim kodzie:

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
źródło
6
To rozwiązanie bardzo mi się podoba. Głównie dlatego, że zmusza użytkownika do wybrania własnego kalendarza (jeśli ma więcej niż jeden).
Sebastian Roth
2
jak uczynić to kompatybilnym dla Androida 2.2?
Srikanth Pai
13
Powinieneś użyć .setData (CalendarContract.Events.CONTENT_URI) zamiast setType, ponieważ z setType (string) spowoduje to awarię na niektórych urządzeniach!
Informatic0re
4
Pełny tutorial tutaj: code.tutsplus.com/tutorials/ ... Lepiej używać stałych, aby uniknąć literówek;)
Adrien Cadet
7
Twój kod nakazuje aplikacji wysyłanie danych do innej aplikacji (kalendarza), która następnie wykorzystuje te dane do dodania nowego wydarzenia w kalendarzu. Twoja aplikacja nie zapisuje ani nie odczytuje danych kalendarza, więc nie potrzebujesz żadnych uprawnień w manifeście.
Singed
66

Użyj tego interfejsu API w swoim kodzie. Pomoże Ci wstawić zdarzenie, wydarzenie z przypomnieniem i wydarzenie ze spotkaniem mogą być włączone ... Ten interfejs API działa na platformie 2.1 i nowszych Ci, którzy używają mniej niż 2.1 zamiast contentu: // com .android.calendar / events używają 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", "[email protected]");// 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;

}
Pradeep
źródło
4
Dodałem event.put("eventTimezone", "UTC/GMT +2:00")i wyeliminowałem event.put("visibility", 3)i event.put("transparency", 0)działa dobrze
validcat
1
Może pojawi się błąd strefy czasowej. Dodaję to i jego prace eventValues.put ("eventTimezone", TimeZone.getDefault (). GetID ());
Cüneyt
2
Dostaję android.database.sqlite.SQLiteExceptionna liniiUri reminderUri = curActivity.getApplicationContext().getContentResolver().insert(Uri.parse(reminderUriString), reminderValues);
Sibidharan
1
ale jeden, gdy ustawiam values.put ("rrule", "FREQ = DAILY"); i ustaw endDate, to nie działa. wydarzenie ustawione na wszystkie dni nie do daty zakończenia. @AmitabhaBiswas
urvi joshi
1
wartości.put (CalendarContract.Reminders.CALENDAR_ID, 1); values.put (CalendarContract.Reminders.TITLE, "Routine Everyday1"); values.put (CalendarContract.Reminders.DTSTART, millisecondsTimesEveryday); wartości.put (CalendarContract.Reminders.HAS_ALARM, prawda); values.put ("rrule", "FREQ = DAILY"); // UNTIL = 1924885800000 values.put (CalendarContract.Reminders.DTEND, EndtimeInMilliseconds); @AmitabhaBiswas
urvi joshi
57

użyłem poniższego kodu, rozwiązuje mój problem dodawania zdarzenia w domyślnym kalendarzu urządzenia w ICS, a także w wersji mniejszej niż 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, "[email protected],[email protected]");
         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);
        }

Mam nadzieję, że to pomoże .....

Milan Shukla
źródło
o Build.VERSION.SDK_INT> 14, jak mogę dodać domyślne przypomnienie na 60 minut i jak mogę uzyskać identyfikator przypomnienia? Dzięki
user1796624
Cześć, zastanawiałem się, czy można zmodyfikować ekran pokazujący edytowalne pola kalendarza (np. Zmienić wygląd niektórych widoków)?
Yulric Sequeira
@ user1950599 Zdecydowanie nie. Zamiar rozpoczyna działanie z innej aplikacji, a jedyną interakcją z nią są dane, które wysyłasz za pośrednictwem intencji.
Pijusn
8

Na wszelki wypadek, jeśli ktoś potrzebuje tego dla platformy Xamarin w języku 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);

Funkcje pomocnicze:

    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
źródło
7

Kalendarz Google to „natywna” aplikacja kalendarza. O ile wiem, wszystkie telefony są dostarczane z zainstalowaną wersją, a domyślny SDK zapewnia wersję.

Możesz zapoznać się z tym samouczkiem, aby z nim pracować.

Cheryl Simon
źródło
7

Spróbuj tego ,

   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);
Arun Antoney
źródło
4

jeśli masz podany ciąg Date z datą i godziną.

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

użyj poniższego kodu, aby dodać wydarzenie z datą i godziną do kalendarza

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);
Bieg
źródło
3

musisz dodać flagę:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

lub spowodujesz błąd z:

startActivity() spoza kontekstu działania wymaga FLAG_ACTIVITY_NEW_TASK

john vuong
źródło