記一次向系統日曆寫入數據的經歷

       最近接到一個向系統日曆裏寫入事件的需求,因爲以前沒作過這個,猜想多是系統數據庫的增刪改查操做。可是第一次聽到這個需求仍是有點慌的,萬一各個不一樣廠商要分別處理怎麼辦,萬一低版本系統不支持怎麼辦,因此我第一時間對這個功能進行了調研。出乎意外地順利地是,只須要網上一搜索「android 寫入日曆事件」,便有了不少的結果,在此必須感謝大牛們的無私分享,也堅決了本身要多寫博客的信心,因此今天把我處理日曆需求的通過給你們分享一下。java

系統的日曆數據庫是哪一個,什麼是日曆帳號,如何申請本身的日曆帳號?

       這裏直接貼出代碼中使用到的數據庫uri以及日曆帳戶,其中前三個是系統數據庫的uri,這裏咱們一一來解釋。第一個是日曆數據庫的總uri,必需要有這個uri才能打開系統的日曆數據庫。第二個是事件uri,若是想向日歷中插入事件,在系統的contentResolver中傳入這個key。第三個是給系統添加提醒,有了這個提醒之後,到點了就會在通知欄顯示出日曆通知(固然前提是app有通知欄權限)。最後的4個都是本app在系統日曆中的帳戶信息,用來給系統做區分的,隨便填填就行了android

private static String CALENDER_URL = "content://com.android.calendar/calendars";
private static String CALENDER_EVENT_URL = "content://com.android.calendar/events";
private static String CALENDER_REMINDER_URL = "content://com.android.calendar/reminders";
private static String CALENDARS_NAME = "aaaa";
private static String CALENDARS_ACCOUNT_NAME = "aaaa@aaaa.com";
private static String CALENDARS_ACCOUNT_TYPE = "com.android.aaaa";
private static String CALENDARS_DISPLAY_NAME = "aaaa帳戶";複製代碼

檢查是否有日曆帳號,若是沒有帳號就添加一個git


添加日曆帳戶也是數據庫操做,具體代碼以下:github


代碼來操做系統日曆須要什麼權限?數據庫

在安卓生態中,作不少操做都須要權限,更別提這是操做系統日曆了。讀寫日曆權限分別是bash

Manifest.permission.READ_CALENDAR複製代碼
Manifest.permission.WRITE_CALENDAR複製代碼

首先咱們要在manifest裏面靜態申請一下app

<uses-permission android:name="android.permission.READ_CALENDAR"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>複製代碼

其次,爲了知足高API要求,還須要在實際使用的地方動態申請日曆權限,代碼以下,這裏面的rxjava代碼暫時不看,後面會講到測試


應該怎麼樣去寫入和刪除日曆?       spa

寫入和刪除日曆其實就是系統數據庫操做,這些代碼很是簡單,基本複製過去就可使用。我這裏不直接貼代碼是由於排版會錯亂,後面我會貼上另一個寫得比較好的帖子的連接,我也是從那裏參考來的,感興趣的話能夠去那邊複製。以下圖,設置好了日曆須要的參數,而後調用系統contentResolver的insert方法進行寫入到庫中以及提醒中,其中event.put(CalendarContract.Events.DTSTART, start);操作系統

就是設置提醒的時間,時間是以毫秒爲單位


刪除也是同樣,調用數據庫方法便可


坑點來了,這是滿滿的乾貨

按照上面的方式半個小時就調通了寫入和刪除日曆功能,可是通常解決問題的時間比實際功能開發的時間老是要多很多,否則就不會出現那麼多的bug了。哈哈,廢話少說,直接乾貨送上

坑點一  個別手機在插入日曆的時候會crash

安卓生態就是這麼奇葩,各類各樣的定製系統,各類各樣的系統版本,因此咱們無法測試到全部手機的兼容性,正因如此,因此纔會常常碰到很奇怪的問題。在插入的時候報錯了,具體錯誤以下:


定位到這行錯誤的源碼出,就是在寫入日曆時失敗了,報了一個空指針。出現的機率很低,是在SIMULATOR 6.0.1的版本上出現的,這手機確實不多見,沒人知道是什麼狀況,可是問題仍是要解決一下滴,否則crash率就降不下來了。因爲是系統插入失敗,因此這裏很差干預,我是直接作了一個try..catch處理了,反正不報bug心情就舒暢了哈哈。


坑點二 部分手機明明沒有日曆權限,系統給你返回有權限

這問題真的是頭痛了半天,這裏必須吐槽一下。出問題的是oppo r9手機上,用戶關閉了日曆權限之後,系統給返回有權限,可是又寫不進去日曆。吐槽完了,問題仍是得本身來解決,誰讓測試小姐姐那麼可愛呢。通過我一整套流程的debug,發現只要沒權限,系統給返回的cursor必定是爲null的,這樣就有了解決思路了,只須要在每次執行插入和刪除前多加一個cursor是否爲null的判斷就行了,說幹就幹,代碼以下:


這就是前面在申請權限是有那麼多的CalendarReminderUtils.isNoCursor(App.getInstance())的緣由,這也是對碎片化滿滿的無奈啊。。。


坑點三 如何判斷是否添加成功

上面說到了部分手機可能在沒權限的時候返回有權限,那麼在添加之後就不能保證目前百分百添加成功了。若是添加失敗了,就應該給一個彈框或者提示。我這裏只能是在添加後再判斷一下系統數據庫中是否有數據,若是沒有數據的話就彈無權限的框,爲了兼容那少部分手機也是沒辦法了,必須多作不少的操做。這裏若是沒權限,就調用showWaringDialog方法來顯示彈框提示用戶要給日曆權限



坑點四 須要先刪除以前的提醒再添加,不支持修改

       最初的話是每調用一次就添加一個提醒,因此後面日曆裏都塞滿了相似的提醒,感受真的很low,而日曆數據庫又不支持修改,因此須要注意的是每次在新增時須要考慮是否須要刪除以前的日曆,否則日曆裏就會愈來愈多重複的事件。在刪除後,再添加具體的新日曆提醒,具體代碼以下圖:


坑點五 有些手機上刪除不了日曆事件

       這是在一臺三星手機上覆現的,其餘國內品牌手機都沒有這問題。就是調用了系統的刪除日曆代碼,也沒有報任何錯誤,可是去系統數據庫查找的時候那條日曆事件仍是存在,和沒刪除一個樣。

       這個問題是在stackoverflow上面找到了答案,說是三星手機刪除日曆事件是屬於軟刪除,即將deleted這個flag置爲0的方式來刪除,三星也喜歡玩非大衆化,否則我們擁有強大心臟的安卓開發者早就已經習慣了。

這個解決方法是在查詢時加一個條件,就是deleted != 1,由於被刪除了在三星上就是0


總結:android向日歷中寫入事件整體來講仍是比較簡單的,沒有想象中不一樣平臺不一樣實現方式那麼恐怖,網上的例子不少,拷貝過去稍微改改就能用了,有需求的能夠在下面的連接中複製代碼,我這裏就再也不贅述了。因此基本實現不太值錢,可是實際項目中碰到的坑點就很可貴了,我這裏已經把我碰到的坑點都列舉了出來,但願能對你們有所幫助。

demo地址:github.com/dongrong-fu…

相關文章
相關標籤/搜索