¿Cómo agregar eventos de calendario en Android?

159

Me estoy poniendo al día con Android, y hoy, en una reunión de proyecto, alguien dijo que Android no tiene una aplicación de calendario nativa, por lo que los usuarios solo usan la aplicación de calendario que deseen.

¿Es esto cierto? De ser así, ¿cómo agrego programáticamente un evento al calendario del usuario? ¿Hay una API común que todos compartan?

Por lo que vale, probablemente estemos apuntando a Android 2.x.

Peter Nelson
fuente
Probablemente deberías aceptar la respuesta de oriharel ya que él proporciona el código para realizar tu tarea.
jww
1
@SumitSharma parece que su enlace ya no funciona, y parece bastante sospechoso con el diálogo de instalación automática.
arreglar

Respuestas:

17

¿Cómo agrego programáticamente un evento al calendario del usuario?

Cual calendario

¿Hay una API común que todos compartan?

No, no más de lo que existe una "API común que todos comparten" para las aplicaciones de calendario de Windows. Existen algunos formatos de datos comunes (por ejemplo, iCalendar) y protocolos de Internet (por ejemplo, CalDAV), pero no hay una API común. Algunas aplicaciones de calendario ni siquiera ofrecen una API.

Si hay aplicaciones de calendario específicas con las que desea integrarse, comuníquese con sus desarrolladores y determine si ofrecen una API. Entonces, por ejemplo, la aplicación Calendario del proyecto de código abierto de Android, que Mayra cita, no ofrece API documentadas y compatibles. Google incluso les ha dicho explícitamente a los desarrolladores que no usen las técnicas descritas en el tutorial que Mayra cita.

Otra opción es agregar eventos al calendario de Internet en cuestión. Por ejemplo, la mejor manera de agregar eventos a la aplicación Calendario desde el proyecto de código abierto de Android es agregar el evento al Google Calendar del usuario a través de las API de GData apropiadas.


ACTUALIZAR

Android 4.0 (API Nivel 14) agregado a CalendarContract ContentProvider.

CommonsWare
fuente
66
No queremos apuntar a un calendario específico, solo queremos poder agregar eventos a cualquier calendario que el usuario esté usando, solo para su conveniencia. Nuestra aplicación proporciona una interfaz para un sitio web que organiza reuniones y conferencias profesionales. Entonces, si alguien se inscribe en uno, sería bueno incluirlo en su calendario.
Peter Nelson el
3
@Peter Nelson: "No queremos apuntar a un calendario específico, solo queremos poder agregar eventos a cualquier calendario que el usuario esté usando, solo para su conveniencia". - No puede hacer eso en Android más de lo que puede hacerlo en Windows. En ninguna de las plataformas sabe "cualquier calendario que esté utilizando el usuario", y en ninguna de las plataformas hay una API universal para trabajar con dicha aplicación de calendario.
CommonsWare
22
No sé por qué sigues comparándolo con Windows: todos los que conozco usan su teléfono para organizar sus horarios y citas, no conozco a nadie que haga eso en su PC, tal vez sea algo generacional. Pero entiendo que Android no puede hacer eso. Gracias.
Peter Nelson el
55
@Peter Nelson: Sigo comparándolo con Windows porque la gente hace las mismas suposiciones. Muchos desarrolladores piensan que pueden "agregar eventos a cualquier calendario que el usuario esté usando" en Windows, porque piensan que todos usan Outlook y, por lo tanto, solo hay un "calendario cualquiera".
CommonsWare
1
@Yar: "El calendario principal del teléfono Android, que tiene cualquier teléfono Android". - a excepción de todos los dispositivos Android que no tienen esa aplicación. Por ejemplo, muchos dispositivos HTC no tienen esa aplicación, sino que tienen su propia aplicación de calendario, como el HTC DROID Incredible seis pulgadas a mi izquierda. Los fabricantes de dispositivos pueden reemplazar la aplicación de calendario, o casi cualquier otra aplicación, con su propia implementación.
CommonsWare
290

Prueba esto en tu código:

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
fuente
66
Me gusta mucho esta solución. Principalmente porque empuja al usuario a seleccionar su propio calendario (si tiene más de uno).
Sebastian Roth, el
2
¿Cómo hacer que esto sea compatible con Android 2.2?
Srikanth Pai
13
Debería usar .setData (CalendarContract.Events.CONTENT_URI) en lugar de setType, porque con setType (string) se bloqueará en algunos dispositivos.
Informatic0re
44
Tutorial completo aquí: code.tutsplus.com/tutorials/… Es mejor usar constantes para evitar errores tipográficos;)
Adrien Cadet
77
Su código le dice a su aplicación que envíe datos a otra aplicación (calendario) que luego usa esos datos para agregar un nuevo evento de calendario. Su aplicación no escribe ni lee datos del calendario, por lo que no necesita ningún permiso en el manifiesto.
Singed
66

Use esta API en su código. Le ayudará a insertar un evento, se puede habilitar un evento con recordatorio y un evento con reunión ... Esta API funciona para la plataforma 2.1 y superior Aquellos que usan menos de 2.1 en lugar de contenido: // com .android.calendar / events usa contenido: // 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
fuente
44
He añadido event.put("eventTimezone", "UTC/GMT +2:00")y eliminado event.put("visibility", 3)e event.put("transparency", 0)y funciona bien
validcat
1
Quizás obtenga un error de zona horaria. Agrego esto y sus trabajos eventValues.put ("eventTimezone", TimeZone.getDefault (). GetID ());
Cüneyt
2
Me estoy poniendo android.database.sqlite.SQLiteExceptionen líneaUri reminderUri = curActivity.getApplicationContext().getContentResolver().insert(Uri.parse(reminderUriString), reminderValues);
Sibidharan
1
pero uno cuando configuro values.put ("rrule", "FREQ = DAILY"); y establecer endDate, no funciona. evento establecido para todos los días, hasta la fecha de finalización. @AmitabhaBiswas
urvi joshi
1
values.put (CalendarContract.Reminders.CALENDAR_ID, 1); values.put (CalendarContract.Reminders.TITLE, "Routine Everyday1"); values.put (CalendarContract.Reminders.DTSTART, millisecondsTimesEveryday); valores.put (CalendarContract.Reminders.HAS_ALARM, verdadero); values.put ("rrule", "FREQ = DAILY"); // UNTIL = 1924885800000 values.put (CalendarContract.Reminders.DTEND, EndtimeInMilliseconds); @AmitabhaBiswas
urvi joshi
57

utilicé el siguiente código, resuelve mi problema al agregar un evento en el calendario predeterminado del dispositivo en ICS y también en la versión menos que 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);
        }

Espero que ayude .....

Milan Shukla
fuente
sobre Build.VERSION.SDK_INT> 14, ¿cómo puedo agregar un recordatorio predeterminado durante 60 minutos y cómo puedo obtener el Id del recordatorio? Gracias
user1796624
Hola, me preguntaba si es posible modificar la pantalla que muestra los campos editables del calendario (como cambiar cómo se ven algunas de las vistas).
Yulric Sequeira
@ user1950599 Definitivamente no. La intención inicia una Actividad desde otra aplicación y la única interacción con ella son los datos que envía a través de la intención.
Pijusn
8

En caso de que alguien necesite esto para Xamarin en 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);

Funciones de ayuda:

    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
fuente
7

Google calendar es la aplicación de calendario "nativa". Hasta donde yo sé, todos los teléfonos vienen con una versión instalada, y el SDK predeterminado proporciona una versión.

Puede consultar este tutorial para trabajar con él.

Cheryl Simon
fuente
7

Prueba esto ,

   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
fuente
4

si tiene una cadena de fecha dada con fecha y hora.

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

use el siguiente código para agregar un evento con fecha y hora al calendario

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
fuente
3

tienes que agregar bandera:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

o causarás un error con:

startActivity() desde fuera de un contexto de actividad requiere el FLAG_ACTIVITY_NEW_TASK

john vuong
fuente