28

我想在 android 4+ 中以编程方式(直接)添加日历事件。这可以在模拟器上测试吗?我没有安卓手机。一些示例代码将不胜感激。我阅读了 android 开发人员的日历提供程序,但我很困惑。如何将事件添加到用户的默认日历?我不需要同步。

编辑:我不想启动添加 Intent 的事件。相反,我想完全从代码中添加它们,而不是启动另一个活动。我需要能够在模拟器上测试事件将被添加到设备默认用户的主日历中。如何设置模拟器来查看用户的默认日历?

4

7 回答 7

45

是我最终做到的一个工作示例:

ContentResolver cr = ctx.getContentResolver();
ContentValues values = new ContentValues();
    
values.put(CalendarContract.Events.DTSTART, dtstart);
values.put(CalendarContract.Events.TITLE, title);
values.put(CalendarContract.Events.DESCRIPTION, comment);

TimeZone timeZone = TimeZone.getDefault();
values.put(CalendarContract.Events.EVENT_TIMEZONE, timeZone.getID());

// Default calendar
values.put(CalendarContract.Events.CALENDAR_ID, 1);

values.put(CalendarContract.Events.RRULE, "FREQ=DAILY;UNTIL="
        + dtUntill);
// Set Period for 1 Hour
values.put(CalendarContract.Events.DURATION, "+P1H");

values.put(CalendarContract.Events.HAS_ALARM, 1);

// Insert event to calendar
Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);

dtuntil在哪里

SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyyMMdd");
Calendar dt = Calendar.getInstance();

// Where untilDate is a date instance of your choice, for example 30/01/2012
dt.setTime(untilDate);

// If you want the event until 30/01/2012, you must add one day from our day because UNTIL in RRule sets events before the last day
dt.add(Calendar.DATE, 1);
String dtUntill = yyyyMMdd.format(dt.getTime());

参考:Recurrence Rule

于 2012-12-27T14:15:09.637 回答
20

我相信您正在寻找的部分是使用意图插入事件。在本节中,它描述了如何为要添加的事件创建一个意图,然后模拟器上的默认日历程序将响应并添加它。您可能必须设置一个虚拟配置文件,以便日历程序在您确实希望看到它接收到正确信息时启动。


来自Android 开发网站的代码:

Calendar beginTime = Calendar.getInstance();
beginTime.set(2012, 0, 19, 7, 30);
Calendar endTime = Calendar.getInstance();
endTime.set(2012, 0, 19, 8, 30);
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);
于 2012-12-04T18:34:25.207 回答
5

不要忘记向清单添加权限

<uses-permission android:name="android.permission.READ_CALENDAR"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>

代码来自:-> Android Dev Site

long calID = 3; // Make sure to which calender you want to add event 
long startMillis = 0;
long endMillis = 0;
Calendar beginTime = Calendar.getInstance();
beginTime.set(2012, 9, 14, 7, 30);
startMillis = beginTime.getTimeInMillis();
Calendar endTime = Calendar.getInstance();
endTime.set(2012, 9, 14, 8, 45);
endMillis = endTime.getTimeInMillis();


ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(Events.DTSTART, startMillis);
values.put(Events.DTEND, endMillis);
values.put(Events.TITLE, "Hackathon");
values.put(Events.DESCRIPTION, "do some code");
values.put(Events.CALENDAR_ID, calID);
values.put(Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
Uri uri = cr.insert(Events.CONTENT_URI, values);

// get the event ID that is the last element in the Uri
long eventID = Long.parseLong(uri.getLastPathSegment());
于 2019-04-04T06:31:18.297 回答
3

使用此代码,您可以以编程方式将事件添加到设备日历。我已经在 Marshmallow 中进行了测试,它对我来说效果很好。

private void addToDeviceCalendar(String startDate,String endDate, String title,String description, String location) {

        String stDate = startDate;
        String enDate = endDate;

        GregorianCalendar calDate = new GregorianCalendar();
        //GregorianCalendar calEndDate = new GregorianCalendar();

        SimpleDateFormat originalFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        SimpleDateFormat targetFormat = new SimpleDateFormat("yyyy,MM,dd,HH,mm");
        Date date,edate;
        try {
            date = originalFormat.parse(startDate);
            stDate=targetFormat.format(date);

        } catch (ParseException ex) {}

        long startMillis = 0;
        long endMillis = 0;
        String dates[] = stDate.split(",");

        SD_YeaR = dates[0];
        SD_MontH = dates[1];
        SD_DaY = dates[2];
        SD_HouR = dates[3];
        SD_MinutE = dates[4];


        /*Log.e("YeaR ", SD_YeaR);
        Log.e("MontH ",SD_MontH );
        Log.e("DaY ", SD_DaY);
        Log.e(" HouR", SD_HouR);
        Log.e("MinutE ", SD_MinutE);*/

        calDate.set(Integer.parseInt(SD_YeaR), Integer.parseInt(SD_MontH)-1, Integer.parseInt(SD_DaY), Integer.parseInt(SD_HouR), Integer.parseInt(SD_MinutE));
        startMillis = calDate.getTimeInMillis();
/*
        try {
            edate = originalFormat.parse(endDate);
            enDate=targetFormat.format(edate);

        } catch (ParseException ex) {}


        String end_dates[] = endDate.split(",");

        String ED_YeaR = end_dates[0];
        String ED_MontH = end_dates[1];
        String ED_DaY = end_dates[2];

        String ED_HouR = end_dates[3];
        String ED_MinutE = end_dates[4];


        calEndDate.set(Integer.parseInt(ED_YeaR), Integer.parseInt(ED_MontH)-1, Integer.parseInt(ED_DaY), Integer.parseInt(ED_HouR), Integer.parseInt(ED_MinutE));
        endMillis = calEndDate.getTimeInMillis();*/

        try {
            ContentResolver cr = getActivity().getContentResolver();
            ContentValues values = new ContentValues();
            values.put(CalendarContract.Events.DTSTART, startMillis);
            values.put(CalendarContract.Events.DTEND, calDate.getTimeInMillis() + 60 * 60 * 1000);
            values.put(CalendarContract.Events.TITLE, title);
            values.put(CalendarContract.Events.DESCRIPTION, description);
            values.put(CalendarContract.Events.EVENT_LOCATION,location);
            values.put(CalendarContract.Events.HAS_ALARM,1);
            values.put(CalendarContract.Events.CALENDAR_ID, 1);
            values.put(CalendarContract.Events.EVENT_TIMEZONE, Calendar.getInstance()
                    .getTimeZone().getID());
            System.out.println(Calendar.getInstance().getTimeZone().getID());
            if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {

                return;
            }
            Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);

            long eventId = Long.parseLong(uri.getLastPathSegment());
            Log.d("Ketan_Event_Id", String.valueOf(eventId));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
于 2016-11-12T05:18:15.337 回答
2

这是询问用户必须将事件添加到哪个日历的方法。因为我的要求是这样,并没有在一个地方找到解决方案。我已经总结并提出了这个解决方案,希望它可以帮助某人:)

final ContentResolver cr = this.getContentResolver();
        Cursor cursor ;
        if (Integer.parseInt(Build.VERSION.SDK) >= 8 )
            cursor = cr.query(Uri.parse("content://com.android.calendar/calendars"), new String[]{ "_id", "calendar_displayName" }, null, null, null);
        else
            cursor = cr.query(Uri.parse("content://calendar/calendars"), new String[]{ "_id", "displayname" }, null, null, null);
        if (cursor != null && cursor.moveToFirst() ) {
            final String[] calNames = new String[cursor.getCount()];
            final int[] calIds = new int[cursor.getCount()];
            for (int i = 0; i < calNames.length; i++) {
                calIds[i] = cursor.getInt(0);
                calNames[i] = cursor.getString(1);
                cursor.moveToNext();
            }

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            final long startDate = sdf.parse(slotData.getSlot_date() + " " + slotData.getSlot_from()).getTime();
            final long endDate = sdf.parse(slotData.getSlot_date() + " " + slotData.getSlot_to()).getTime();

            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Select any one");
            builder.setSingleChoiceItems(calNames, -1, new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    ContentValues cv = new ContentValues();
                    cv.put("calendar_id", calIds[which]);
                    cv.put("title", title);
                    cv.put("dtstart", startDate);
                    cv.put("hasAlarm", 1);
                    cv.put("dtend", endDate);
                    cv.put("eventTimezone", TimeZone.getDefault().getID());

                    Uri newEvent ;
                    if (Integer.parseInt(Build.VERSION.SDK) >= 8 )
                        newEvent = cr.insert(Uri.parse("content://com.android.calendar/events"), cv);
                    else
                        newEvent = cr.insert(Uri.parse("content://calendar/events"), cv);

                    if (newEvent != null) {
                        long id = Long.parseLong( newEvent.getLastPathSegment() );
                        ContentValues values = new ContentValues();
                        values.put( "event_id", id );
                        values.put( "method", 1 );
                        values.put( "minutes", 15 ); // 15 minutes
                        if (Integer.parseInt(Build.VERSION.SDK) >= 8 )
                            cr.insert( Uri.parse( "content://com.android.calendar/reminders" ), values );
                        else
                            cr.insert( Uri.parse( "content://calendar/reminders" ), values );

                    }
                    dialog.cancel();
                }

            });

            builder.create().show();
        }
        if (cursor != null) {
            cursor.close();
        }
于 2018-10-31T10:37:40.900 回答
1

同意以上所有答案,但导入的是日历 ID。您不能使用 1,因为三星手机使用 1 作为他们的日历(S Planner)。所以日历 ID 是您想要事件的电子邮件的 ID。您可以通过以下特定事件的代码获取日历 ID

int calenderId=-1;
        String calenderEmaillAddress="xxx@gmail.com";
        String[] projection = new String[]{
                CalendarContract.Calendars._ID,
                CalendarContract.Calendars.ACCOUNT_NAME};
        ContentResolver cr = activity.getContentResolver();
        Cursor cursor = cr.query(Uri.parse("content://com.android.calendar/calendars"), projection,
                CalendarContract.Calendars.ACCOUNT_NAME + "=? and (" +
                        CalendarContract.Calendars.NAME + "=? or " +
                        CalendarContract.Calendars.CALENDAR_DISPLAY_NAME + "=?)",
                new String[]{calenderEmaillAddress, calenderEmaillAddress,
                        calenderEmaillAddress}, null);

        if (cursor.moveToFirst()) {

            if (cursor.getString(1).equals(calenderEmaillAddress))
                 calenderId=cursor.getInt(0); //youre calender id to be insered in above 2 answer


        }
于 2017-06-02T10:34:55.753 回答
1

在阅读了几篇文章并尝试了几次之后。我终于发现这种方法在 Android 8 和 10 上运行良好。

我的代码:

    public void addEventToCalendar() {
    Context myContext = getContext();
    String[] projection = {"_id", "calendar_displayName"};
    Cursor calCursor = myContext.getContentResolver().query(CalendarContract.Calendars.CONTENT_URI, projection, CalendarContract.Calendars.VISIBLE + " = 1 AND "  + CalendarContract.Calendars.IS_PRIMARY + "=1", null, CalendarContract.Calendars._ID + " ASC");
    if(calCursor.getCount() <= 0){
        calCursor = myContext.getContentResolver().query(CalendarContract.Calendars.CONTENT_URI, projection, CalendarContract.Calendars.VISIBLE + " = 1", null, CalendarContract.Calendars._ID + " ASC");
    }

    while (calCursor.moveToNext()) {
        long id = calCursor.getLong(calCursor.getColumnIndexOrThrow(CalendarContract.Calendars._ID));
        long startMillis;
        long endMillis;
        Calendar beginTime = Calendar.getInstance();
        beginTime.set(2021, 9, 22, 15, 30);
        startMillis = beginTime.getTimeInMillis();
        Calendar endTime = Calendar.getInstance();
        endTime.set(2021, 9, 22, 16, 45);
        endMillis = endTime.getTimeInMillis();

        ContentResolver cr = Objects.requireNonNull(getActivity()).getContentResolver();
        ContentValues values = new ContentValues();
        values.put(CalendarContract.Events.DTSTART, startMillis);
        values.put(CalendarContract.Events.DTEND, endMillis);
        values.put(CalendarContract.Events.TITLE, "My event");
        values.put(CalendarContract.Events.DESCRIPTION, "Nice description");
        values.put(CalendarContract.Events.CALENDAR_ID, id);
        Log.i("ID","my Id"+ id);
        values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
        Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);

        long eventID = Long.parseLong(uri.getLastPathSegment());
    }

}

我能够在不同的手机上进行测试,并且插入是在谷歌日历以及基本的安卓日历上完成的。

通常,此方法确保将事件插入设备上所有可用的日历中。我无法测试它,但我寄予厚望。

于 2021-11-18T14:34:26.680 回答