Android Calendar Provider总结

本文详细介绍了Android的Calendar Provider,它是存储用户日程和事件的数据库。通过它,开发者可以在不启动应用的情况下利用系统日历进行提醒操作,例如各种提醒功能的实现。文章重点讨论了CalendarContract.Calendars表,强调了ownerAccount字段的重要性,并提供了读写权限声明及新增事件的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

官方文档:https://developer.android.com/guide/topics/providers/calendar-provider.html

一、什么是Calendar Provider

    其实是就是Android专门用于存储用户的日程与日程事件的数据库,通过读写日程与日程事件相关数据可以不需要启动自己的应用而借助于系统日历应用做一些提醒用户的操作,应用场景:还贷提醒、计划提醒、图书馆还书提醒等。

二、Calendar数据库中重要的表

1、CalendarContract.Calendars:该表的作用是每条记录存放单独的日程详情,日程可以简单理解成用户的一个计划,而事件就是这个计划的一些通知,比如提醒、有没有开始、完成了没有等。具体有如下的字段:最重要的就是ownerAccount,也叫做cal_id,因为事件的加入、提醒都需要使用这个id,可以叫做日程账户。

             0 = "ownerAccount"
             1 = "sync_events"
             2 = "cal_sync6"
             3 = "cal_sync8"
             4 = "maxReminders"
             5 = "canPartiallyUpdate"
             6 = "_sync_id"
             7 = "COALESCE(isPrimary, ownerAccount = account_name)"
             8 = "allowedReminders"
             9 = "_id"
             10 = "calendar_timezone"
             11 = "calendar_access_level"
             12 = "calendar_displayName"
             13 = "dirty"
             14 = "cal_sync10"
             15 = "calendar_color"
             16 = "cal_sync3"
             17 = "cal_sync9"
             18 = "cal_sync1"
             19 = "canOrganizerRespond"
             20 = "cal_sync7"
             21 = "canModifyTimeZone"
             22 = "visible"
             23 = "account_type"
             24 = "allowedAttendeeTypes"
             25 = "cal_sync2"
             26 = "mutators"
             27 = "calendar_location"
             28 = "allowedAvailability"
             29 = "calendar_color_index"
             30 = "name"
             31 = "cal_sync5"
             32 = "deleted"
             33 = "account_name"
             34 = "cal_sync4"

(1)日程数据库的读写需要声明权限,代码如下:

    <uses-permission android:name="android.permission.READ_CALENDAR" />
    <uses-permission android:name="android.permission.WRITE_CALENDAR" />
(2)新增一个日程,代码如下:

private static String CALENDARS_NAME = "Tips";
    private static String CALENDARS_ACCOUNT_NAME = "TipsAccount";
    private static String CALENDARS_ACCOUNT_TYPE = CalendarContract.ACCOUNT_TYPE_LOCAL;
    private static String CALENDARS_DISPLAY_NAME = "Hello";

    public static long addNewCalendar(Context context) {
        TimeZone timeZone = TimeZone.getDefault();
        ContentValues value = new ContentValues();
        value.put(CalendarContract.Calendars.NAME, CALENDARS_NAME);

        value.put(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME);
        value.put(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE);
        value.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CALENDARS_DISPLAY_NAME);
        value.put(CalendarContract.Calendars.VISIBLE, 1);
        value.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.BLUE);
        value.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER);
        value.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
        value.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, timeZone.getID());
        value.put(CalendarContract.Calendars.OWNER_ACCOUNT, CALENDARS_ACCOUNT_NAME);
        value.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 0);

        Uri calendarUri = CalendarContract.Calendars.CONTENT_URI;
        calendarUri = calendarUri.buildUpon()
                .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
                .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME)
                .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE)
                .build();

        Uri result = context.getContentResolver().insert(calendarUri, value);
        long id = result == null ? -1 : ContentUris.parseId(result);
        LogDebug("addNewCalendar: " + id);
        return id;
    }
(3)查询日程,代码如下:
    public static long queryCalendar(Context context, ContentResolver contentResolver) {
        long calID = -1;
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_CALENDAR) != PackageManager
                .PERMISSION_GRANTED) {
            return calID;
        }

        Uri uri = CalendarContract.Calendars.CONTENT_URI;
        Cursor cur = contentResolver.query(uri, null, null, null, null);
        while (cur != null && cur.moveToNext()) {
            calID = cur.getLong(0);
            String calendarTimezone = cur.getString(10);
            String syncEvents = cur.getString(1);
            String displayName = cur.getString(12);
            String accountName = cur.getString(33);
            LogDebug("queryCalendar: calID=" + calID + ",syncEvents=" + syncEvents + ",displayName=" + displayName +
                    ",calendarTimezone=" + calendarTimezone + "," + "accountName=" + accountName);
        }
        if (cur != null) {
            cur.close();
        }
        return calID;
    }

2、CalendarContract.Events:创建了日程之后,就是各种事件提醒等操作了,为此Android专门设计了这个表来存放事件。该表的作用是每条记录存放单独的事件信息,例如事件标题、开始与结束时间等。注意一个事件可以出现一次或者重复出现。

(1)往日程新增一个事件,代码如下:

public static long addEvent(long calID, Context context, long beginTime) {
        LogDebug("addEvent calID:" + calID);
        long eventID = -1;
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_CALENDAR) != PackageManager
                .PERMISSION_GRANTED) {
            return eventID;
        }

        Calendar mCalendar = Calendar.getInstance();
        mCalendar.setTimeInMillis(beginTime);//设置开始时间
        long start = mCalendar.getTime().getTime();
        mCalendar.setTimeInMillis(start + 2 * 60 * 60 * 1000);//设置终止时间
        long end = mCalendar.getTime().getTime();

        ContentValues values = new ContentValues();
        //必要参数
        values.put(CalendarContract.Events.CALENDAR_ID, calID);
        //必要参数
        values.put(CalendarContract.Events.EVENT_TIMEZONE, getEventTimezone());
        values.put(CalendarContract.Events.DTSTART, start);
        //非重复事件时必须设置
        values.put(CalendarContract.Events.DTEND, end);
        values.put(CalendarContract.Events.TITLE, "Calendar Event");
        values.put(CalendarContract.Events.DESCRIPTION, "research the system calendar event");

        Uri uri = context.getContentResolver().insert(CalendarContract.Events.CONTENT_URI, values);
        // get the event ID that is the last element in the Uri
        eventID = Long.parseLong(uri.getLastPathSegment());
        LogDebug("eventID:" + eventID);
        return eventID;
    }
(2)更新事件信息,代码如下:

public static void updateEvents(Context context, long eventID) {
        Calendar beginTime = getInstance();
        beginTime.set(2017, 6, 21, 18, 20);
        long startMillis = beginTime.getTimeInMillis();
        Calendar endTime = getInstance();
        endTime.set(2017, 6, 21, 20, 0);
        long endMillis = endTime.getTimeInMillis();

        ContentValues values = new ContentValues();
        values.put(CalendarContract.Events.DTSTART, startMillis);
        values.put(CalendarContract.Events.DTEND, endMillis);
        // The new title for the event
        values.put(CalendarContract.Events.TITLE, "Kickboxing");

        Uri updateUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID);
        int rows = context.getContentResolver().update(updateUri, values, null, null);
        LogDebug("updateEvents: " + rows);
    }
(3)删除事件,代码如下:
public static void deleteEvents(Context context, long eventID) {
        ContentValues values = new ContentValues();
        Uri deleteUri = null;
        deleteUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID);
        int rows = context.getContentResolver().delete(deleteUri, null, null);
        LogDebug("deleteEvents: " + rows);
    }
3、CalendarContract.Reminders:加入了事件之后,其实最关心的还是这个提醒操作,而android而专门设计了这张表来存放事件提醒的信息。代码如下:
public static void addReminders(Context context, long eventID) {
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_CALENDAR) != PackageManager
                .PERMISSION_GRANTED) {
            return;
        }
        ContentValues values = new ContentValues();
        values.put(CalendarContract.Reminders.MINUTES, 10);
        values.put(CalendarContract.Reminders.EVENT_ID, eventID);
        values.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);
        Uri uri = context.getContentResolver().insert(CalendarContract.Reminders.CONTENT_URI, values);
        LogDebug("addReminders uri:" + uri);
    }
4、CalendarContract.Instances:事件提醒操作能够得以保证实施,其实记录时间点是最关键的,为次android也专门设计了这个表,用于存放事件的开始与结束时间,与事件的发生次数有对应关系。一次性事件对应一条记录,重复事件对应多条记录。代码就不上了,参考官方文档即可。

5、CalendarContract.Attendees:该表的作用是存放事件的参与者信息。代码如下:

public static void addAttendees(Context context, long eventID) {
        ContentValues values = new ContentValues();
        values.put(CalendarContract.Attendees.ATTENDEE_NAME, "Dson");
        values.put(CalendarContract.Attendees.ATTENDEE_EMAIL, "dsonr@example.com");
        values.put(CalendarContract.Attendees.ATTENDEE_RELATIONSHIP, CalendarContract.Attendees.RELATIONSHIP_ATTENDEE);
        values.put(CalendarContract.Attendees.ATTENDEE_TYPE, CalendarContract.Attendees.TYPE_OPTIONAL);
        values.put(CalendarContract.Attendees.ATTENDEE_STATUS, CalendarContract.Attendees.ATTENDEE_STATUS_INVITED);
        values.put(CalendarContract.Attendees.EVENT_ID, eventID);
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_CALENDAR) != PackageManager
                .PERMISSION_GRANTED) {
            return;
        }
        Uri uri = context.getContentResolver().insert(CalendarContract.Attendees.CONTENT_URI, values);
        LogDebug("addAttendees uri:" + uri);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值