Android日歷事件管理器,是時(shí)候?yàn)槟愕腁PP增加一個(gè)事件提醒功能啦!

前言

很多時(shí)候,我們需要向APP中添加一個(gè)事件提醒功能,一般的話都是通過微信公眾號(hào)或是發(fā)送手機(jī)短信的方式來實(shí)現(xiàn),但這樣如果對于個(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é)尾有附源碼鏈接)

效果預(yù)覽.gif

怎么樣?心不心動(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ò)):

image

Events表

既然Events這張表對我們實(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 事件所針對的時(shí)區(qū)
EVENT_END_TIMEZONE 針對事件結(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 參與者是否能夠邀請其他參與者
GUESTS_CAN_SEE_GUESTS 參與者是否能夠看到與會(huì)者列表

Events基本上就是這么多了,我們操作的話只需要根據(jù)對應(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);
        // 事件描述(對應(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表中找到與之對應(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ù)庫的同學(xué)肯定都很了解,這里我就不再介紹了。??

其實(shí)最主要的還是了解表的各個(gè)字段的含義,了解了這些字段,再將他們都組裝起來插入到系統(tǒng)表中就可以了,總體實(shí)現(xiàn)起來沒有什么難點(diǎn),相對來說還是比較簡單的。??

這里我就只簡單介紹下其中的CalendarContract.Events表啦。有關(guān)與CalendarContract的更多操作,有興趣的同學(xué)可以參考下Android 日歷CalendarProvider這篇文章,詳細(xì)的講解了有關(guān)CalendarContract的各個(gè)表以及含義。

最后,不要忘了在注冊清單中加入讀寫系統(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ù)文章,真的是太太太興奮啦?。?!??以此作為自己成長的第一步,加油?。?!????
涉及到的知識(shí)點(diǎn)主要有:

如果你僅僅只是想使用,快速提供這樣一個(gè)功能的話,直接copy一份源碼到自己的項(xiàng)目中即可使用。

【參考】Android 日歷CalendarProvider

戳我看源碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容