前言
很多時候,我們需要向APP中添加一個事件提醒功能,一般的話都是通過微信公眾號或是發送手機短信的方式來實現,但這樣如果對于個人開發者的話,想通過這兩種方法來實現通知提醒功能就有些限制了。你以為我們就要就此止步了???別著急,還有辦法!幸運的是Android系統為我們提供了CalendarContract這個類,系統有關于日歷的操作等等都是通過他實現噠!所以我們可以借助CalendarContract來實現向系統日歷中插入事件。而且既然是插入到系統日歷中,所以我們當然也就不用擔心服務會因為內存不夠被系統殺掉而導致提醒不及時的問題!哇!開心辣么大??!
繼續前進,這次給大家帶來的就是通過Android系統的CalendarContract類來封裝實現的一個日歷事件工具類,目前實現的功能有向系統日歷插入日歷賬戶、查詢日歷賬戶、添加、修改、刪除日歷事件以及事件提醒等功能。廢話少說,看效果圖:(整個工程的代碼還是比較多的,為了節省篇幅,這里只截取一小部分的代碼,如果想查看完整代碼,結尾有附源碼鏈接)
怎么樣?心不心動?!趕快借此給自己的APP加上一個事件提醒功能吧!
CalendarContract.Events
這是什么?Google代碼遵循的見其名知其意相信大家看到這個名字就應該大概猜到了他的作用吧?這張表保存了特定的事件信息。在這個表中每一行都有單一事件的信息,如事件的標題、位置、開始時間、結束時間等。這個事件能夠發生一次或重復發生多次。會議、提醒和擴展的屬性被保存的獨立的表中,它們都有一個EVENT_ID跟Events表中的_ID進行關聯。最終事件也就是插入到系統的這張表中,還有一個CalendarContract.Reminders,它主要是用來保存事件的提醒參數的,比如說設置提前15分鐘、使用系統通知提醒作為提醒方式,這兩個參數的值就是保存在CalendarContract.Reminders中的
下面來看張日歷事件的數據模型圖(素材來自網絡):
Events表
既然Events這張表對我們實現這次的功能如此重要,那就讓我們來看看他都提供了哪些字段:
字段 | 描述 |
---|---|
CALENDAR_ID | 事件所屬的日歷的_ID |
ORGANIZER | 事件的組織者(所有者)的電子郵件 |
TITLE | 事件的標題 |
EVENT_LOCATION | 事件發生的地點 |
DESCRIPTION | 事件的標題 |
DTSTART | 事件的開始時間,使用從紀元開始的UTC毫秒計時 |
DTEND | 事件的結束時間,使用從紀元開始的UTC毫秒計時 |
EVENT_TIMEZONE | 事件所針對的時區 |
EVENT_END_TIMEZONE | 針對事件結束時間的時區 |
DURATION | 用RFC5545格式表示的事件持續時間,例如“PT1H”表示事件持續1小時的狀態, “P2W”指明2周的持續時間 |
ALL_DAY | 1指明這個事件會占用整天時間(由本地時區定義的時間);0指明它是一個普通的事件,可以在一天的任何時間開始和結束 |
RRULE | 格式化的事件復發規則(RFC5545)。如“FREQ=WEEKLY;COUNT=10;WKST=SU” |
RDATE | 事件的復發日期。通常RDATE要聯合RRULE一起使用來定義一個重復發生的事件的合集。 |
AVAILABILITY | 事件的標題 |
GUESTS_CAN_MODIFY | 參與者是否能夠修改事件 |
GUESTS_CAN_INVITE_OTHERS | 參與者是否能夠邀請其他參與者 |
GUESTS_CAN_SEE_GUESTS | 參與者是否能夠看到與會者列表 |
Events基本上就是這么多了,我們操作的話只需要根據對應的字段進行數據的組裝然后再通過ContentResolver將其插入到系統的表中。
組裝數據:
/**
* 組裝日歷事件
*
* @param startTime 開始時間
* @param endTime 結束時間
* @param eventTitle 事件標題
* @param eventDes 事件描述
* @param eventLocation 事件地點
* @param event 組裝的事件
*/
private static void setupEvent(long startTime, long endTime, String eventTitle, String eventDes,
String eventLocation, ContentValues event) {
// 事件開始時間
event.put(CalendarContract.Events.DTSTART, startTime);
// 事件結束時間
event.put(CalendarContract.Events.DTEND, endTime);
// 事件標題
event.put(CalendarContract.Events.TITLE, eventTitle);
// 事件描述(對應手機系統日歷備注欄)
event.put(CalendarContract.Events.DESCRIPTION, eventDes);
// 事件地點
event.put(CalendarContract.Events.EVENT_LOCATION, eventLocation);
// 事件時區
event.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
// 定義事件的顯示,默認即可
event.put(CalendarContract.Events.ACCESS_LEVEL, CalendarContract.Events.ACCESS_DEFAULT);
// 事件的狀態
event.put(CalendarContract.Events.STATUS, 0);
// 設置事件提醒警報可用
event.put(CalendarContract.Events.HAS_ALARM, 1);
// 設置事件忙
event.put(CalendarContract.Events.AVAILABILITY, CalendarContract.Events.AVAILABILITY_BUSY);
// 設置事件重復規則
// event.put(CalendarContract.Events.RRULE, );
}
插入事件:
Uri eventUri = context.getContentResolver().insert(uri1, event);
其中第二個參數event就是上面組裝出的數據。
其他的更新和刪除操作都類似,就是通過ID在Events表中找到與之對應的事件實體,再調用update方法或delete將其更新或是刪除。
更新事件:
context.getContentResolver().update(uri, event, selection, selectionArgs);
刪除事件:
context.getContentResolver().delete(uri1, selection, selectionArgs);
其中最后兩個參數selection和selectionArgs就是數據的匹配條件了,熟悉數據庫的同學肯定都很了解,這里我就不再介紹了。??
其實最主要的還是了解表的各個字段的含義,了解了這些字段,再將他們都組裝起來插入到系統表中就可以了,總體實現起來沒有什么難點,相對來說還是比較簡單的。??
這里我就只簡單介紹下其中的CalendarContract.Events表啦。有關與CalendarContract的更多操作,有興趣的同學可以參考下Android 日歷CalendarProvider這篇文章,詳細的講解了有關CalendarContract的各個表以及含義。
最后,不要忘了在注冊清單中加入讀寫系統日歷的權限哦,不然是無法實現功能滴。??
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
總結
啊啊?。〉谝淮螌懠夹g文章,真的是太太太興奮啦?。?!??以此作為自己成長的第一步,加油!?。????
涉及到的知識點主要有:
如果你僅僅只是想使用,快速提供這樣一個功能的話,直接copy一份源碼到自己的項目中即可使用。