在android 4中如何在没有Intent的情况下静默添加日历事件到默认日历?

时间:2012-12-04 18:26:52

标签: java android android-calendar

我想在android 4+中以编程方式(直接)添加日历事件。是否可以在仿真器上进行测试?我没有自己的Android手机。一些示例代码将不胜感激。我读了Android开发者的日历提供程序,但我很困惑。如何将事件添加到用户的默认日历?我不需要同步。

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

6 个答案:

答案 0 :(得分:37)

Here是我最终成功的例子:

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

答案 1 :(得分:11)

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


来自Android Dev Site的代码:

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);

答案 2 :(得分:2)

使用此代码,您可以以编程方式将事件添加到设备日历。我在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();
        }
    }

答案 3 :(得分:2)

不要忘记向清单添加权限

 <add name="Access-Control-Allow-Origin" value="*" />
 <add name="Access-Control-Allow-Headers" value="Key,Content-Type" />
 <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />

来自:-> Android Dev Site

的代码
SEC7123: Request header Key was not present in the Access-Control-Allow-Headers list.

答案 4 :(得分: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


        }

答案 5 :(得分:0)

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

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();
        }