Bagaimana cara menambahkan acara kalender di Android?

159

Saya baru saja mempercepat Android, dan hari ini dalam rapat proyek seseorang berkata bahwa Android tidak memiliki aplikasi kalender asli sehingga pengguna hanya menggunakan aplikasi kalender apa pun yang mereka suka.

Apakah ini benar, dan jika demikian, bagaimana saya secara program menambahkan acara ke kalender pengguna? Apakah ada API umum yang mereka bagikan?

Untuk apa nilainya, kami mungkin menargetkan Android 2.x.

Peter Nelson
sumber
Anda mungkin harus menerima jawaban oriharel karena dia memberikan kode untuk menyelesaikan tugas Anda.
jww
1
@SumitSharma tautan Anda tampaknya tidak berfungsi lagi - dan tampaknya cukup mencurigakan dengan dialog instal otomatis.
perbaiki

Jawaban:

17

bagaimana cara menambahkan acara ke kalender pengguna secara terprogram?

Kalender yang mana?

Apakah ada API umum yang mereka bagikan?

Tidak, tidak lebih dari ada "API umum yang mereka semua bagikan" untuk aplikasi kalender Windows. Ada beberapa format data umum (misalnya, iCalendar) dan protokol Internet (misalnya, CalDAV), tetapi tidak ada API umum. Beberapa aplikasi kalender bahkan tidak menawarkan API.

Jika ada aplikasi kalender khusus yang ingin Anda integrasikan, hubungi pengembangnya dan tentukan apakah mereka menawarkan API. Jadi, misalnya, aplikasi Kalender dari proyek open source Android, yang mengutip Mayra, tidak menawarkan API yang terdokumentasi dan didukung. Google bahkan secara eksplisit mengatakan kepada pengembang untuk tidak menggunakan teknik yang diuraikan dalam tutorial yang dikutip Mayra.

Pilihan lain adalah bagi Anda untuk menambahkan acara ke kalender Internet yang dimaksud. Misalnya, cara terbaik untuk menambahkan acara ke aplikasi Kalender dari proyek sumber terbuka Android adalah menambahkan acara ke Kalender Google pengguna melalui API GData yang sesuai.


MEMPERBARUI

Android 4.0 (API Level 14) menambahkan a CalendarContract ContentProvider.

CommonsWare
sumber
6
Kami tidak ingin menargetkan kalender tertentu - kami hanya ingin dapat menambahkan acara ke kalender apa pun yang digunakan pengguna, sama seperti kenyamanan bagi pengguna. Aplikasi kami menyediakan antarmuka ke situs web yang menyelenggarakan pertemuan dan konferensi profesional. Jadi, jika seseorang mendaftar, alangkah baiknya memasukkannya ke kalender mereka.
Peter Nelson
3
@Peter Nelson: "Kami tidak ingin menargetkan kalender tertentu - kami hanya ingin dapat menambahkan acara ke kalender apa pun yang digunakan pengguna, sama seperti kenyamanan bagi pengguna." - Anda tidak dapat melakukannya di Android lebih dari yang Anda bisa lakukan pada Windows. Di kedua platform, Anda tahu "kalender apa pun yang digunakan pengguna", dan pada platform apa pun tidak ada API universal untuk bekerja dengan aplikasi kalender semacam itu.
CommonsWare
22
Saya tidak tahu mengapa Anda terus membandingkannya dengan Windows - Semua orang yang saya tahu menggunakan telepon mereka untuk mengatur jadwal dan janji mereka - Saya tidak tahu siapa pun yang melakukan itu di PC mereka - mungkin itu hal yang umum. Tapi saya tahu Android tidak bisa melakukan itu. Terima kasih.
Peter Nelson
5
@ Peter Nelson: Saya terus membandingkannya dengan Windows karena orang membuat asumsi yang sama. Banyak pengembang berpikir mereka dapat "menambahkan acara ke kalender apa pun yang digunakan pengguna" di Windows, karena mereka pikir semua orang menggunakan Outlook, dan karenanya hanya ada satu "kalender apa pun".
CommonsWare
1
@Yar: "Kalender ponsel Android utama, yang dimiliki semua ponsel Android." - Kecuali untuk semua perangkat Android yang tidak memiliki aplikasi itu. Sebagai contoh, banyak perangkat HTC tidak memiliki aplikasi itu, melainkan memiliki aplikasi kalender mereka sendiri, seperti HTC DROID Incredible enam inci di sebelah kiri saya. Pabrikan perangkat dipersilakan untuk mengganti aplikasi kalender - atau hampir semua aplikasi lain - dengan penerapannya sendiri.
CommonsWare
290

Coba ini di kode Anda:

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
sumber
6
Saya suka solusi ini. Terutama karena ini mendorong pengguna untuk memilih kalendernya sendiri (jika ia memiliki lebih dari satu).
Sebastian Roth
2
bagaimana membuat ini kompatibel untuk android 2.2?
Srikanth Pai
13
Anda harus menggunakan .setData (CalendarContract.Events.CONTENT_URI) alih-alih setType, karena dengan setType (string) itu akan crash pada beberapa perangkat!
Informatic0re
4
Tutorial lengkap di sini: code.tutsplus.com/tutorials/... Lebih baik menggunakan konstanta untuk menghindari kesalahan ketik;)
Adrien Cadet
7
Kode Anda memberi tahu aplikasi Anda untuk mengirim data ke aplikasi (kalender) lain yang kemudian menggunakan data itu untuk menambahkan acara kalender baru. Aplikasi Anda tidak menulis atau membaca data kalender, jadi Anda tidak memerlukan izin apa pun dalam manifes.
Bernyanyi
66

Gunakan API ini dalam kode Anda .. Ini akan membantu Anda memasukkan acara, acara dengan pengingat dan acara dengan rapat dapat diaktifkan ... Api ini berfungsi untuk platform 2.1 dan di atas Mereka yang menggunakan kurang dari 2.1 alih-alih konten: // com .android.calendar / events menggunakan konten: // kalender / acara

 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
sumber
4
Saya menambahkan event.put("eventTimezone", "UTC/GMT +2:00")dan menghilangkannya event.put("visibility", 3)dan event.put("transparency", 0)itu berfungsi dengan baik
validcat
1
Mungkin mendapatkan kesalahan zona waktu. Saya menambahkan ini dan kerjanya eventValues.put ("eventTimezone", TimeZone.getDefault (). GetID ());
Cüneyt
2
Saya mulai android.database.sqlite.SQLiteExceptionantriUri reminderUri = curActivity.getApplicationContext().getContentResolver().insert(Uri.parse(reminderUriString), reminderValues);
Sibidharan
1
tetapi satu ketika saya menetapkan nilai.put ("aturan", "FREQ = SETIAP HARI"); dan mengatur endDate, itu tidak berfungsi. acara ditetapkan untuk semua hari tidak sampai tanggal akhir. @AmitabhaBiswas
urvi joshi
1
values.put (CalendarContract.Reminders.CALENDAR_ID, 1); values.put (CalendarContract.Reminders.TITLE, "Rutin Setiap Hari1"); values.put (CalendarContract.Reminders.DTSTART, milidetikTimesEveryday); values.put (CalendarContract.Reminders.HAS_ALARM, true); values.put ("rrule", "FREQ = SETIAP HARI"); // SAMPAI = 1924885800000 values.put (CalendarContract.Reminders.DTEND, EndtimeInMilliseconds); @AmitabhaBiswas
urvi joshi
57

saya menggunakan kode di bawah ini, itu memecahkan masalah saya untuk menambahkan acara di kalender perangkat default di ICS dan juga pada versi kurang dari 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);
        }

Semoga ini bisa membantu .....

Milan Shukla
sumber
tentang Build.VERSION.SDK_INT> 14, bagaimana saya bisa menambahkan pengingat default selama 60 menit dan bagaimana saya bisa mendapatkan Id pengingat? Terima kasih
user1796624
Hai, saya bertanya-tanya apakah mungkin untuk mengubah layar yang menampilkan bidang kalender yang dapat diedit (seperti mengubah bagaimana beberapa tampilan terlihat)?
Yulric Sequeira
@ user1950599 Jelas tidak. Intent memulai suatu Kegiatan dari aplikasi lain dan satu-satunya interaksi dengannya adalah data yang Anda kirim melalui niat.
Pijusn
40

Pada Android versi 4.0, API dan niat resmi tersedia untuk berinteraksi dengan penyedia kalender yang tersedia .

tobsen
sumber
4
Komentar yang benar-benar bermanfaat, tidak bisa cukup Menekankan ini :)
Warpzit
1
Mungkin Anda bisa memberikan beberapa kode untuk mengikuti jawaban hanya tautan?
jww
8

Untuk jaga-jaga jika seseorang membutuhkan ini untuk Xamarin di 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);

Fungsi Helper:

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

Kalender Google adalah aplikasi kalender "asli". Sejauh yang saya tahu, semua ponsel dilengkapi dengan versi yang diinstal, dan SDK default menyediakan versi.

Anda mungkin melihat tutorial ini untuk bekerja dengannya.

Cheryl Simon
sumber
7

Coba ini ,

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

jika Anda memiliki string Tanggal yang diberikan dengan tanggal dan waktu.

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

gunakan kode berikut untuk menambahkan acara dengan tanggal dan waktu ke kalender

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

Anda harus menambahkan bendera:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

atau Anda akan menyebabkan kesalahan dengan:

startActivity() dari luar konteks Aktivitas memerlukan FLAG_ACTIVITY_NEW_TASK

john vuong
sumber