Como adicionar eventos da agenda no Android?

159

Estou começando a me atualizar no Android e, hoje, em uma reunião de projeto, alguém disse que o Android não possui aplicativo de calendário nativo para que os usuários usem o aplicativo de calendário que quiserem.

Isso é verdade e, em caso afirmativo, como adiciono programaticamente um evento ao calendário do usuário? Existe uma API comum que todos compartilhem?

Pelo que vale, provavelmente estamos segmentando o Android 2.x.

Peter Nelson
fonte
Você provavelmente deve aceitar a resposta de oriharel, pois ele fornece o código para realizar sua tarefa.
JWW
1
@SumitSharma, seu link parece não funcionar mais - e parece bastante suspeito com a caixa de diálogo de instalação automática.
correção

Respostas:

17

como adiciono programaticamente um evento ao calendário do usuário?

Qual calendário?

Existe uma API comum que todos compartilhem?

Não, não há mais do que uma "API comum que todos compartilhem" para aplicativos de calendário do Windows. Existem alguns formatos de dados comuns (por exemplo, iCalendar) e protocolos da Internet (por exemplo, CalDAV), mas nenhuma API comum. Alguns aplicativos de calendário nem oferecem uma API.

Se houver aplicativos de calendário específicos com os quais você deseja integrar, entre em contato com os desenvolvedores e determine se eles oferecem uma API. Por exemplo, o aplicativo Calendário do projeto de código aberto Android, que Mayra cita, não oferece APIs documentadas e suportadas. O Google até disse explicitamente aos desenvolvedores para não usarem as técnicas descritas no tutorial que Mayra cita.

Outra opção é adicionar eventos ao calendário da Internet em questão. Por exemplo, a melhor maneira de adicionar eventos ao aplicativo Calendário a partir do projeto de código aberto Android é adicionar o evento ao Google Calendar do usuário por meio das APIs GData apropriadas.


ATUALIZAR

Android 4.0 (API Nível 14) adicionou a CalendarContract ContentProvider.

CommonsWare
fonte
6
Não queremos segmentar um calendário específico - apenas queremos adicionar eventos a qualquer calendário que o usuário esteja usando, apenas para sua conveniência. Nosso aplicativo fornece uma interface para um site que organiza reuniões e conferências profissionais. Portanto, se alguém se inscrever em um, seria bom colocá-lo em seu calendário.
Peter Nelson
3
@ Peter Nelson: "Não queremos segmentar um calendário específico - queremos adicionar eventos a qualquer calendário que o usuário esteja usando, apenas para sua conveniência". - você não pode fazer isso no Android da mesma forma que no Windows. Em nenhuma plataforma você conhece "qualquer calendário que o usuário esteja usando" e em nenhuma plataforma existe uma API universal para trabalhar com esse aplicativo de calendário.
CommonsWare
22
Não sei por que você continua comparando com o Windows - todo mundo que conhece usa o telefone para organizar horários e compromissos - não conheço ninguém que faz isso no PC - talvez seja uma coisa geracional. Mas entendo que o Android não pode fazer isso. Obrigado.
Peter Nelson
5
@ Peter Nelson: Eu continuo comparando com o Windows porque as pessoas fazem as mesmas suposições. Muitos desenvolvedores pensam que podem "adicionar eventos a qualquer calendário que o usuário esteja usando" no Windows, porque pensam que todo mundo usa o Outlook e, portanto, existe apenas um "qualquer calendário".
CommonsWare
1
@Yar: "O principal calendário do telefone Android, que qualquer telefone Android possui." - exceto para todos os dispositivos Android que não possuem esse aplicativo. Por exemplo, muitos dispositivos HTC não possuem esse aplicativo, mas possuem seu próprio aplicativo de calendário, como o HTC DROID Incredible seis polegadas à minha esquerda. Os fabricantes de dispositivos podem substituir o aplicativo de calendário - ou qualquer outro aplicativo - por sua própria implementação.
CommonsWare
290

Tente isso no seu 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
fonte
6
Eu gosto muito desta solução. Principalmente porque leva o usuário a selecionar seu próprio calendário (se ele tiver mais de um).
Sebastian Roth
2
como fazer isso compatível para android 2.2?
Srikanth Pai
13
Você deve usar .setData (CalendarContract.Events.CONTENT_URI) em vez de setType, porque com setType (string) ele trava em alguns dispositivos!
Informatic0re
4
Tutorial completo aqui: code.tutsplus.com/tutorials/... É melhor constantes de uso para evitar erros de digitação;)
Adrien Cadet
7
Seu código diz ao seu aplicativo para enviar dados para outro aplicativo (calendário) que, em seguida, usa esses dados para adicionar um novo evento do calendário. Seu aplicativo não grava nem lê dados de calendário, portanto, você não precisa de permissões no manifesto.
Cantado
66

Use esta API no seu código. Isso ajudará você a inserir evento, evento com lembrete e evento com reunião pode ser ativado ... Esta API funciona para a plataforma 2.1 e superior Aqueles que usam menos de 2.1 em vez do conteúdo: // com .android.calendar / events usa o conteúdo: // 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
fonte
4
Eu adicionei event.put("eventTimezone", "UTC/GMT +2:00")e eliminada event.put("visibility", 3)e event.put("transparency", 0)e funciona bem
validcat
1
Talvez obtenha um erro de fuso horário. Eu adiciono isso e seus trabalhos eventValues.put ("eventTimezone", TimeZone.getDefault (). GetID ());
06515 Cüneyt
2
Estou entrando android.database.sqlite.SQLiteExceptionna linha #Uri reminderUri = curActivity.getApplicationContext().getContentResolver().insert(Uri.parse(reminderUriString), reminderValues);
3100 Sibidharan
1
mas uma quando defino values.put ("rrule", "FREQ = DAILY"); e defina endDate, não está funcionando. evento definido para todos os dias até a data final. @AmitabhaBiswas
urvi joshi
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 = DIARIAMENTE"); // ATÉ = 1924885800000 values.put (CalendarContract.Reminders.DTEND, EndtimeInMilliseconds); @AmitabhaBiswas
urvi joshi
57

eu usei o código abaixo, resolve meu problema para adicionar evento no calendário padrão do dispositivo no ICS e também na versão menos que o 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 ajude .....

Milan Shukla
fonte
sobre o Build.VERSION.SDK_INT> 14, como posso adicionar um lembrete padrão por 60 minutos e como obter o ID do lembrete? Graças
user1796624
Oi, eu queria saber se é possível modificar a tela que mostra os campos editáveis ​​do calendário (como alterar a aparência de algumas das visualizações)?
User1950599
@ user1950599 Definitivamente não. O Intent inicia uma Atividade a partir de outro aplicativo e a única interação com ele são os dados que você envia através do Intent.
Pijusn
8

Caso alguém precise disso para o Xamarin em 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);

Funções auxiliares:

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

O calendário do Google é o aplicativo de calendário "nativo". Até onde eu sei, todos os telefones vêm com uma versão instalada e o SDK padrão fornece uma versão.

Você pode conferir este tutorial para trabalhar com ele.

Cheryl Simon
fonte
7

Tente isso,

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

se você tiver uma determinada sequência de datas com data e hora.

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

use o código a seguir para adicionar um evento com data e hora ao calendário

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);
Uma corrida
fonte
3

você precisa adicionar sinalizador:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

ou você causará erro com:

startActivity() de fora de um contexto de atividade requer o FLAG_ACTIVITY_NEW_TASK

john vuong
fonte