简体   繁体   English

如何在 android 4 中无意图地将日历事件添加到默认日历中?

[英]How to add calendar events to default calendar, silently without Intent, in android 4?

I want to add calendar events programmatically (directly) in android 4+.我想在 android 4+ 中以编程方式(直接)添加日历事件。 Is it this possible to be tested on emulator?这是否可以在模拟器上进行测试? I don't own an android phone.我没有安卓手机。 Some sample code would be appreciated.一些示例代码将不胜感激。 I read Calendar Provider of android developers but I'm confused.我阅读了 android 开发人员的日历提供程序,但我很困惑。 How can I add events to the default calendar of a user?如何将事件添加到用户的默认日历? I don't need to be synced.我不需要同步。

EDIT: I do not want to launch an event adding Intent.编辑:我不想启动添加 Intent 的事件。 Instead I want to add them completely from code and not launch another activity.相反,我想完全从代码中添加它们,而不是启动另一个活动。 I need to be able to test on an emulator that the events will be added to the main calendar of the default user of the device.我需要能够在模拟器上测试事件将被添加到设备默认用户的主日历中。 How do I set up an emulator to view the default calendar of the user?如何设置模拟器以查看用户的默认日历?

Here is a working example of what i eventually made it: 是我最终做到的一个工作示例:

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

where dtuntil is 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());

Ref: Recurrence Rule 参考: Recurrence Rule

I believe the section you are looking for is Using an intent to insert an event . 我相信您要查找的部分是使用意图插入事件 In this section it describes how to create an intent for the event you want to add and then the default calender program on the emulator will respond and add it. 在本节中,它描述了如何为要添加的事件创建意图,然后模拟器上的默认日历程序将响应并添加它。 You may have to set up a dummy profile so that the calendar program will start if you actually want to see that it receives the correct information. 您可能必须设置虚拟配置文件,以便在您确实希望看到它收到正确信息时启动日历程序。


Code from Android Dev Site : 来自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);

Using this code, you can programmatically add an event to device calendar. 使用此代码,您可以以编程方式将事件添加到设备日历。 I have tested in Marshmallow, and it works fine for me. 我在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();
        }
    }

Dont Forget to add Permission to Manifest 别忘了向Manifest添加权限

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

Code from :-> Android Dev Site 代码来自: - > 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());

Agree with above all answers but import is calender Id. 同意以上所有答案,但导入是日历ID。 you can not use 1 as samsung phone uses 1 for their calender(S Planner).So calender ID is id for which email you want event. 你不能使用1作为三星手机使用1作为他们的日历(S Planner)。所以日历ID是您想要活动的电子邮件的ID。 you can get calender id by following code for specific event 您可以通过以下代码获取特定事件的日历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


        }

Here is the way to ask user to which calendar the event has to be added. 以下是询问用户必须添加事件的日历的方法。 As my requirement was this and didn't find the solution at one place. 正如我的要求是这样,并没有在一个地方找到解决方案。 I have summarized and came up with this solution, hope it helps someone :) 我已经总结并提出了这个解决方案,希望它可以帮助某人:)

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

After reading several posts and after a few tries.在阅读了几篇文章并尝试了几次之后。 I finally found this method to work well on Android 8 and 10.我终于发现这种方法在 Android 8 和 10 上运行良好。

My code:我的代码:

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

}

I was able to test on different phones and the insertion is done on the google calendar as well as on a basic android calendar.我能够在不同的手机上进行测试,插入是在谷歌日历和基本的安卓日历上完成的。

Normally this method makes sure to insert the event (s) in all the calendars available on the device.通常,此方法可确保将事件插入设备上的所有可用日历。 I couldn't test it but I have high hopes.我无法测试它,但我寄予厚望。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM