前言
很多時(shí)候怠缸,我們需要向APP中添加一個(gè)事件提醒功能诗轻,一般的話都是通過微信公眾號(hào)或是發(fā)送手機(jī)短信的方式來實(shí)現(xiàn),但這樣如果對(duì)于個(gè)人開發(fā)者的話揭北,想通過這兩種方法來實(shí)現(xiàn)通知提醒功能就有些限制了扳炬。你以為我們就要就此止步了???別著急搔体,還有辦法恨樟!幸運(yùn)的是Android系統(tǒng)為我們提供了CalendarContract這個(gè)類,系統(tǒng)有關(guān)于日歷的操作等等都是通過他實(shí)現(xiàn)噠疚俱!所以我們可以借助CalendarContract來實(shí)現(xiàn)向系統(tǒng)日歷中插入事件劝术。而且既然是插入到系統(tǒng)日歷中,所以我們當(dāng)然也就不用擔(dān)心服務(wù)會(huì)因?yàn)閮?nèi)存不夠被系統(tǒng)殺掉而導(dǎo)致提醒不及時(shí)的問題呆奕!哇养晋!開心辣么大??!
繼續(xù)前進(jìn)梁钾,這次給大家?guī)淼木褪峭ㄟ^Android系統(tǒng)的CalendarContract類來封裝實(shí)現(xiàn)的一個(gè)日歷事件工具類匙握,目前實(shí)現(xiàn)的功能有向系統(tǒng)日歷插入日歷賬戶、查詢?nèi)諝v賬戶陈轿、添加圈纺、修改、刪除日歷事件以及事件提醒等功能麦射。廢話少說蛾娶,看效果圖:(整個(gè)工程的代碼還是比較多的,為了節(jié)省篇幅潜秋,這里只截取一小部分的代碼蛔琅,如果想查看完整代碼,結(jié)尾有附源碼鏈接)
怎么樣峻呛?心不心動(dòng)罗售?!趕快借此給自己的APP加上一個(gè)事件提醒功能吧钩述!
CalendarContract.Events
這是什么寨躁?Google代碼遵循的見其名知其意相信大家看到這個(gè)名字就應(yīng)該大概猜到了他的作用吧?這張表保存了特定的事件信息牙勘。在這個(gè)表中每一行都有單一事件的信息职恳,如事件的標(biāo)題所禀、位置、開始時(shí)間放钦、結(jié)束時(shí)間等色徘。這個(gè)事件能夠發(fā)生一次或重復(fù)發(fā)生多次。會(huì)議操禀、提醒和擴(kuò)展的屬性被保存的獨(dú)立的表中褂策,它們都有一個(gè)EVENT_ID跟Events表中的_ID進(jìn)行關(guān)聯(lián)。最終事件也就是插入到系統(tǒng)的這張表中颓屑,還有一個(gè)CalendarContract.Reminders斤寂,它主要是用來保存事件的提醒參數(shù)的,比如說設(shè)置提前15分鐘邢锯、使用系統(tǒng)通知提醒作為提醒方式,這兩個(gè)參數(shù)的值就是保存在CalendarContract.Reminders中的
下面來看張日歷事件的數(shù)據(jù)模型圖(素材來自網(wǎng)絡(luò)):
Events表
既然Events這張表對(duì)我們實(shí)現(xiàn)這次的功能如此重要搀别,那就讓我們來看看他都提供了哪些字段:
字段 | 描述 |
---|---|
CALENDAR_ID | 事件所屬的日歷的_ID |
ORGANIZER | 事件的組織者(所有者)的電子郵件 |
TITLE | 事件的標(biāo)題 |
EVENT_LOCATION | 事件發(fā)生的地點(diǎn) |
DESCRIPTION | 事件的標(biāo)題 |
DTSTART | 事件的開始時(shí)間丹擎,使用從紀(jì)元開始的UTC毫秒計(jì)時(shí) |
DTEND | 事件的結(jié)束時(shí)間,使用從紀(jì)元開始的UTC毫秒計(jì)時(shí) |
EVENT_TIMEZONE | 事件所針對(duì)的時(shí)區(qū) |
EVENT_END_TIMEZONE | 針對(duì)事件結(jié)束時(shí)間的時(shí)區(qū) |
DURATION | 用RFC5545格式表示的事件持續(xù)時(shí)間歇父,例如“PT1H”表示事件持續(xù)1小時(shí)的狀態(tài)蒂培, “P2W”指明2周的持續(xù)時(shí)間 |
ALL_DAY | 1指明這個(gè)事件會(huì)占用整天時(shí)間(由本地時(shí)區(qū)定義的時(shí)間);0指明它是一個(gè)普通的事件榜苫,可以在一天的任何時(shí)間開始和結(jié)束 |
RRULE | 格式化的事件復(fù)發(fā)規(guī)則(RFC5545)护戳。如“FREQ=WEEKLY;COUNT=10;WKST=SU” |
RDATE | 事件的復(fù)發(fā)日期。通常RDATE要聯(lián)合RRULE一起使用來定義一個(gè)重復(fù)發(fā)生的事件的合集垂睬。 |
AVAILABILITY | 事件的標(biāo)題 |
GUESTS_CAN_MODIFY | 參與者是否能夠修改事件 |
GUESTS_CAN_INVITE_OTHERS | 參與者是否能夠邀請(qǐng)其他參與者 |
GUESTS_CAN_SEE_GUESTS | 參與者是否能夠看到與會(huì)者列表 |
Events基本上就是這么多了媳荒,我們操作的話只需要根據(jù)對(duì)應(yīng)的字段進(jìn)行數(shù)據(jù)的組裝然后再通過ContentResolver將其插入到系統(tǒng)的表中。
組裝數(shù)據(jù):
/**
* 組裝日歷事件
*
* @param startTime 開始時(shí)間
* @param endTime 結(jié)束時(shí)間
* @param eventTitle 事件標(biāo)題
* @param eventDes 事件描述
* @param eventLocation 事件地點(diǎn)
* @param event 組裝的事件
*/
private static void setupEvent(long startTime, long endTime, String eventTitle, String eventDes,
String eventLocation, ContentValues event) {
// 事件開始時(shí)間
event.put(CalendarContract.Events.DTSTART, startTime);
// 事件結(jié)束時(shí)間
event.put(CalendarContract.Events.DTEND, endTime);
// 事件標(biāo)題
event.put(CalendarContract.Events.TITLE, eventTitle);
// 事件描述(對(duì)應(yīng)手機(jī)系統(tǒng)日歷備注欄)
event.put(CalendarContract.Events.DESCRIPTION, eventDes);
// 事件地點(diǎn)
event.put(CalendarContract.Events.EVENT_LOCATION, eventLocation);
// 事件時(shí)區(qū)
event.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
// 定義事件的顯示驹饺,默認(rèn)即可
event.put(CalendarContract.Events.ACCESS_LEVEL, CalendarContract.Events.ACCESS_DEFAULT);
// 事件的狀態(tài)
event.put(CalendarContract.Events.STATUS, 0);
// 設(shè)置事件提醒警報(bào)可用
event.put(CalendarContract.Events.HAS_ALARM, 1);
// 設(shè)置事件忙
event.put(CalendarContract.Events.AVAILABILITY, CalendarContract.Events.AVAILABILITY_BUSY);
// 設(shè)置事件重復(fù)規(guī)則
// event.put(CalendarContract.Events.RRULE, );
}
插入事件:
Uri eventUri = context.getContentResolver().insert(uri1, event);
其中第二個(gè)參數(shù)event就是上面組裝出的數(shù)據(jù)钳枕。
其他的更新和刪除操作都類似,就是通過ID在Events表中找到與之對(duì)應(yīng)的事件實(shí)體赏壹,再調(diào)用update方法或delete將其更新或是刪除鱼炒。
更新事件:
context.getContentResolver().update(uri, event, selection, selectionArgs);
刪除事件:
context.getContentResolver().delete(uri1, selection, selectionArgs);
其中最后兩個(gè)參數(shù)selection和selectionArgs就是數(shù)據(jù)的匹配條件了,熟悉數(shù)據(jù)庫(kù)的同學(xué)肯定都很了解蝌借,這里我就不再介紹了昔瞧。??
其實(shí)最主要的還是了解表的各個(gè)字段的含義,了解了這些字段菩佑,再將他們都組裝起來插入到系統(tǒng)表中就可以了自晰,總體實(shí)現(xiàn)起來沒有什么難點(diǎn),相對(duì)來說還是比較簡(jiǎn)單的稍坯。??
這里我就只簡(jiǎn)單介紹下其中的CalendarContract.Events表啦缀磕。有關(guān)與CalendarContract的更多操作,有興趣的同學(xué)可以參考下Android 日歷CalendarProvider這篇文章,詳細(xì)的講解了有關(guān)CalendarContract的各個(gè)表以及含義袜蚕。
最后糟把,不要忘了在注冊(cè)清單中加入讀寫系統(tǒng)日歷的權(quán)限哦,不然是無法實(shí)現(xiàn)功能滴牲剃。??
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
總結(jié)
啊啊扒卜琛!第一次寫技術(shù)文章凿傅,真的是太太太興奮啦2!聪舒!??以此作為自己成長(zhǎng)的第一步辨液,加油!O洳小滔迈!????
涉及到的知識(shí)點(diǎn)主要有:
- CalendarContract.Events
- CalendarContract.Reminders
- CalendarContract.Calendars
- 一丟丟的數(shù)據(jù)庫(kù) Cursor
如果你僅僅只是想使用,快速提供這樣一個(gè)功能的話被辑,直接copy一份源碼到自己的項(xiàng)目中即可使用燎悍。