Android插入日歷提醒

Android插入日歷提醒

本文用于說明Android日歷功能

Android系統(tǒng)提供了插入日功能。第三方應(yīng)用可以自行插入日歷事件,系統(tǒng)日歷會(huì)根據(jù)日歷事件在設(shè)定的時(shí)間彈出通知提醒用戶。

Android系統(tǒng)日歷提醒原理

Android提供了一個(gè)provider:com.android.providers.calendar? 該provider提供一套接口供開發(fā)者使用。

日歷事件存儲(chǔ)

日歷事件存儲(chǔ)在數(shù)據(jù)庫(kù)里,數(shù)據(jù)庫(kù)的路徑是:

/data/data/com.android.providers.calendar/databases/calendar.db

日歷事件數(shù)據(jù)格式

日歷事件主要涉及三個(gè)數(shù)據(jù)結(jié)構(gòu),也是上面說的數(shù)據(jù)庫(kù)里的三個(gè)表:Calendars、Events、Reminders

Calendars

存儲(chǔ)的是日歷帳號(hào)信息。每個(gè)app都可以往日歷數(shù)據(jù)庫(kù)里注冊(cè)多個(gè)帳號(hào),也可以使用數(shù)據(jù)庫(kù)里已有的帳號(hào)。一般來(lái)講,每個(gè)app注冊(cè)一個(gè)帳號(hào)即可。當(dāng)不需要使用這個(gè)日的時(shí)候,刪除這個(gè)日歷。與這個(gè)日歷綁定的事件和提醒都會(huì)被刪除。

表結(jié)構(gòu)為:



Events

日歷事件,比如今天下午三點(diǎn)要去讀書。這就是一個(gè)事件。在Events表里,每一行數(shù)據(jù)都是一個(gè)事件

表結(jié)構(gòu)為:


表中有一個(gè)字段是calendar_id。用于標(biāo)識(shí)該事件屬于哪個(gè)帳號(hào),該值對(duì)應(yīng)著Calendars表中的_id字段

Reminders

日歷提醒,有了日歷事件。并不代表就會(huì)產(chǎn)生提醒。如果某個(gè)日歷事件需要提醒用戶。需要對(duì)這個(gè)日歷事件創(chuàng)建一個(gè)提醒,告訴系統(tǒng),該事件需要以什么方式提醒用戶

表結(jié)構(gòu):


表中event_id用于標(biāo)識(shí)該提醒屬于哪個(gè)日歷事件。該值對(duì)應(yīng)著Events表中的_id字段


以上三個(gè)表的字段含義這里就不一一解釋了。具體可以看https://developer.android.com/reference/android/provider/CalendarContract.Calendars

https://developer.android.com/reference/android/provider/CalendarContract.Events

https://developer.android.com/reference/android/provider/CalendarContract.Reminders

日歷開發(fā)API

1. 存儲(chǔ)日歷帳號(hào)

? 存儲(chǔ)帳號(hào)信息的URI:android.provider.CalendarContract.Calendars#CONTENT_URI

? DEMO CODE

//Calendar 為自定義日歷數(shù)據(jù)格式,用于存儲(chǔ)用戶創(chuàng)建的帳號(hào)信息

fun addCalendar(calendar: Calendar, resolver:

? ContentResolver): Long {

??? val? calendars = queryCalendar(calendar.ACCOUNT_NAME, calendar.ACCOUNT_TYPE,? calendar.OWNER_ACCOUNT, resolver)

??? if? (calendars != null && calendars.size > 0) {


? Log.d("lzqtest", "CalendarWrapper.addCalendar: already? has a same calendar "+calendars)


? return CalendarStatus.ALREADY_EXIST.value()

??? }

??? val? contentValues = ContentValues()

??? if? (!calendar.ACCOUNT_TYPE.isNullOrEmpty())? {


? contentValues.put(Calendars.ACCOUNT_TYPE,? calendar.ACCOUNT_TYPE)

??? }

??? if? (!calendar.ACCOUNT_NAME.isNullOrEmpty())? {


? contentValues.put(Calendars.ACCOUNT_NAME,? calendar.ACCOUNT_NAME)

??? }

??? if? (!calendar.NAME.isNullOrEmpty()) {


? contentValues.put(Calendars.NAME,? calendar.NAME)

??? }

??? if? (calendar.DIRTY != null) {


? contentValues.put(Calendars.DIRTY,? calendar.DIRTY)

??? }

??? if? (!calendar.MUTATORS.isNullOrEmpty())? {


? contentValues.put(Calendars.MUTATORS,? calendar.MUTATORS)

??? }

??? if? (!calendar.CALENDAR_DISPLAY_NAME.isNullOrEmpty())? {


? contentValues.put(Calendars.CALENDAR_DISPLAY_NAME,? calendar.CALENDAR_DISPLAY_NAME)

??? }

??? if? (calendar.CALENDAR_COLOR != null) {


? contentValues.put(Calendars.CALENDAR_COLOR,? calendar.CALENDAR_COLOR)

??? }

??? if? (calendar.CALENDAR_ACCESS_LEVEL != null) {


? contentValues.put(Calendars.CALENDAR_ACCESS_LEVEL,? calendar.CALENDAR_ACCESS_LEVEL)

??? }

??? if? (!calendar.CALENDAR_LOCATION.isNullOrEmpty())? {


? contentValues.put(Calendars.CALENDAR_LOCATION,? calendar.CALENDAR_LOCATION)

??? }

??? if? (!calendar.CALENDAR_TIME_ZONE.isNullOrEmpty())? {


? contentValues.put(Calendars.CALENDAR_TIME_ZONE,? calendar.CALENDAR_TIME_ZONE)

??? }

??? if? (!calendar.OWNER_ACCOUNT.isNullOrEmpty())? {


? contentValues.put(Calendars.OWNER_ACCOUNT,? calendar.OWNER_ACCOUNT)

??? }

??? if? (calendar.MAX_REMINDERS != null) {


? contentValues.put(Calendars.MAX_REMINDERS,? calendar.MAX_REMINDERS)

??? }

??? if? (!calendar.ALLOWED_REMINDERS.isNullOrEmpty())? {


? contentValues.put(Calendars.ALLOWED_REMINDERS,? calendar.ALLOWED_REMINDERS)

??? }

??? if? (!calendar.ALLOWED_AVAILABILITY.isNullOrEmpty())? {


? contentValues.put(Calendars.ALLOWED_AVAILABILITY,? calendar.ALLOWED_AVAILABILITY)

??? }

??? if? (!calendar.ALLOWED_ATTENDEE_TYPES.isNullOrEmpty())? {


? contentValues.put(Calendars.ALLOWED_ATTENDEE_TYPES,? calendar.ALLOWED_ATTENDEE_TYPES)

??? }

??? var uri? = Calendars.CONTENT_URI

??? //uri需要通過appendQueryParameter 追加參數(shù),否則會(huì)報(bào)插入失敗的錯(cuò)誤

??? uri= uri.buildUpon()


? .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")


? .appendQueryParameter(Calendars.ACCOUNT_NAME,? calendar.ACCOUNT_NAME)


? .appendQueryParameter(Calendars.ACCOUNT_TYPE,


? calendar.ACCOUNT_TYPE)


? .build()

//插入日歷帳號(hào)信息

???? val? ret=resolver.insert(uri, contentValues)


??? return? if (ret!=null) ContentUris.parseId(ret) else CalendarStatus.FAIL.value()


}

2. 存儲(chǔ)日歷事件

? 存儲(chǔ)日歷事件URI:android.provider.CalendarContract.Events#CONTENT_URI

? DEMO CODE

// EVENT 為自定義對(duì)象,用于存儲(chǔ)用戶日歷事件信息

fun addEvent(event: Event, resolver:

? ContentResolver): Long {

??? val? events = queryEventByCalendarId(event.CALENDAR_ID, resolver)

??? if? (events != null && events.size > 0) {

??????? for? (data in events) {


? if (data.TITLE?.equals(event.TITLE) == true

??????????????????? && data.DTSTART? == event.DTSTART

??????????????????? && data.DTEND ==? event.DTEND) {


? Log.d("lzqtest", "EventWrapper.addEvent: alread exist? event $events ")


? return CalendarStatus.ALREADY_EXIST.value()


? }

??????? }

??? }

??? if? (event.CALENDAR_ID == null || event.CALENDAR_ID!! < 0) {


? return CalendarStatus.PARAMETER_ERROR.value()

??? }

??? val? contentValues = ContentValues()


? contentValues.put(CalendarContract.Events.CALENDAR_ID, event.CALENDAR_ID)

??? if? (!event.TITLE.isNullOrEmpty())


? contentValues.put(CalendarContract.Events.TITLE, event.TITLE)

??? if? (!event.EVENT_LOCATION.isNullOrEmpty())


? contentValues.put(CalendarContract.Events.EVENT_LOCATION, event.EVENT_LOCATION)

??? if? (!event.DESCRIPTION.isNullOrEmpty())? {


? contentValues.put(CalendarContract.Events.DESCRIPTION, event.DESCRIPTION)

??? }

??? if? (event.EVENT_COLOR != null) {


? contentValues.put(CalendarContract.Events.EVENT_COLOR, event.EVENT_COLOR)

??? }

??? if? (event.STATUS != null) {


? contentValues.put(CalendarContract.Events.STATUS, event.STATUS)

??? }

??? if? (event.SELF_ATTENDEE_STATUS != null) {


? contentValues.put(CalendarContract.Events.SELF_ATTENDEE_STATUS, event.SELF_ATTENDEE_STATUS)

??? }

??? if? (event.DTSTART != null) {


? contentValues.put(CalendarContract.Events.DTSTART, event.DTSTART)

??? }

??? if? (!event.EVENT_TIMEZONE.isNullOrEmpty())? {


? contentValues.put(CalendarContract.Events.EVENT_TIMEZONE, event.EVENT_TIMEZONE)

??? }

??? if? (event.ALL_DAY != null) {


? contentValues.put(CalendarContract.Events.ALL_DAY, event.ALL_DAY)

??? }

??? if? (event.ACCESS_LEVEL != null) {


? contentValues.put(CalendarContract.Events.ACCESS_LEVEL, event.ACCESS_LEVEL)

??? }

??? if? (event.AVAILABILITY != null) {


? contentValues.put(CalendarContract.Events.AVAILABILITY, event.AVAILABILITY)

??? }

??? if? (event.HAS_ALARM != null) {


? contentValues.put(CalendarContract.Events.HAS_ALARM, event.HAS_ALARM)

??? }

??? if (event.HAS_EXTENDED_PROPERTIES? != null) {


? contentValues.put(CalendarContract.Events.HAS_EXTENDED_PROPERTIES, event.HAS_EXTENDED_PROPERTIES)

??? }

??? if? (!event.RRULE.isNullOrEmpty()) {


? contentValues.put(CalendarContract.Events.RRULE, event.RRULE)

??? }

??? if? (!event.RDATE.isNullOrEmpty()) {


? contentValues.put(CalendarContract.Events.RDATE, event.RDATE)

??? }

??? if? (!event.EXRULE.isNullOrEmpty()) {


? contentValues.put(CalendarContract.Events.EXRULE, event.EXRULE)

??? }

??? if? (!event.EXDATE.isNullOrEmpty()) {


? contentValues.put(CalendarContract.Events.EXDATE, event.EXDATE)

??? }

??? if? (event.ORIGINAL_ID != null) {


? contentValues.put(CalendarContract.Events.ORIGINAL_ID, event.ORIGINAL_ID)

??? }

??? if? (event.LAST_DATE != null) {


? contentValues.put(CalendarContract.Events.LAST_DATE, event.LAST_DATE)

??? }

??? if? (event.HAS_ATTENDEE_DATA != null) {


? contentValues.put(CalendarContract.Events.HAS_ATTENDEE_DATA, event.HAS_ATTENDEE_DATA)

??? }

??? if? (event.GUESTS_CAN_MODIFY != null) {


? contentValues.put(CalendarContract.Events.GUESTS_CAN_MODIFY, event.GUESTS_CAN_MODIFY)

??? }

??? if? (event.GUESTS_CAN_INVITE_OTHERS != null) {


? contentValues.put(CalendarContract.Events.GUESTS_CAN_INVITE_OTHERS, event.GUESTS_CAN_INVITE_OTHERS)

??? }

??? if? (event.GUESTS_CAN_SEE_GUESTS != null) {


? contentValues.put(CalendarContract.Events.GUESTS_CAN_SEE_GUESTS, event.GUESTS_CAN_SEE_GUESTS)

??? }

??? if? (!event.ORGANIZER.isNullOrEmpty())? {


? contentValues.put(CalendarContract.Events.ORGANIZER, event.ORGANIZER)

??? }

??? if? (event.DELETED != null) {


? contentValues.put(CalendarContract.Events.DELETED, event.DELETED)

??? }

??? if? (!event.EVENT_END_TIMEZONE.isNullOrEmpty())? {


? contentValues.put(CalendarContract.Events.EVENT_END_TIMEZONE, event.EVENT_END_TIMEZONE)

??? }


??? if? (event.DTEND != null) {


? contentValues.put(CalendarContract.Events.DTEND, event.DTEND)

??? }


? Log.d("lzqtest", "EventWrapper.addEvent: insert event? now ")

??? val ret? = resolver.insert(CalendarContract.Events.CONTENT_URI,? contentValues)


? Log.d("lzqtest", "EventWrapper.addEvent: insert result? ret=$ret ")

??? return? if (ret != null) ContentUris.parseId(ret) else CalendarStatus.FAIL.value()

}

3. 存儲(chǔ)日歷提醒

? 存儲(chǔ)日歷提醒URI:android.provider.CalendarContract.Reminders#CONTENT_URI

? DEMO CODE


fun addReminder(reminder: Reminder, resolver:

? ContentResolver): Long? {

??? val? reminders = queryMinderByEventId(reminder.EVENT_ID, resolver)

??? if? (reminders != null && reminders.size > 0) {

??????? for? (data in reminders) {


? if (data.MINUTES == (reminder.MINUTES)


? && data.METHOD == reminder.METHOD


? ) {


? Log.d(

??????????????????? "lzqtest",


? "ReminderWrapper.addReminder: alread exist reminder=$reminders? "


? )


? return CalendarStatus.ALREADY_EXIST.value()


? }

??????? }

??? }

??? if? (reminder.EVENT_ID == null) {


? Log.d("lzqtest", "ReminderWrapper.addReminder: EVENT_ID? is null ")


? return CalendarStatus.PARAMETER_ERROR.value()

??? }

??? val? contentValues = ContentValues()


? contentValues.put(CalendarContract.Reminders.EVENT_ID, reminder.EVENT_ID)


??? if? (reminder.METHOD != null) {


? contentValues.put(CalendarContract.Reminders.METHOD, reminder.METHOD)

??? }

??? if? (reminder.MINUTES != null) {


? contentValues.put(CalendarContract.Reminders.MINUTES, reminder.MINUTES)

??? }


? Log.d("lzqtest", "ReminderWrapper.addReminder: add? reminder now ")

??? val ret? = resolver.insert(CalendarContract.Reminders.CONTENT_URI, contentValues)


? Log.d("lzqtest", "ReminderWrapper.addReminder: result? ret=$ret ")

??? return? if (ret == null) CalendarStatus.FAIL.value()? else ContentUris.parseId(ret)

}

按以上方式插入日歷數(shù)據(jù)到provider后,系統(tǒng)日歷app即可顯示插入的日歷提醒。第三方日歷app不一定會(huì)顯示。這取決于第三方日歷app會(huì)不會(huì)去讀取系統(tǒng)日歷數(shù)據(jù)庫(kù)

demo code已上傳至https://github.com/lzqnet/CalendarManager

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

相關(guān)閱讀更多精彩內(nèi)容

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