內容提供者:ContentProvide, 是不同應用程序間進行數據交換的標準API,以URL形式對外提供數據接口;
內容解析者:ContentResolver,根據URL 訪問操作ContentProvide接口。
申請權限
需要對日歷進行增刪改查操作,因此需要在manifest中添加相應的讀寫權限
<uses-permission android:name="android.permission.READ_CALENDAR"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
配置相關的Url
也就是系統日歷Calendar Provide的對外接口,下面的是2.2之后的Url,2.2之前又是一套
反正項目最低版本都遠大于2.2,就不寫了-。-
private final String CALANDER_URL = "content://com.android.calendar/calendars"; // 日歷賬戶
private final String CALANDER_EVENT_URL = "content://com.android.calendar/events"; // 日歷事件
private final String CALANDER_REMIDER_URL = "content://com.android.calendar/reminders"; // 日歷提醒
獲取日歷賬戶
一般來說各大廠商的手機都會預設一個叫手機的日歷賬戶 如果不是就不是吧,我這一打測試機都叫這個我也沒辦法不系orz
當然也不排除有的手機沒有預設的日歷賬戶,比如ASUS Nexus 7,這個時候就需要開發者添加一個賬戶
Tips: 創建賬戶所添加的日程,當創建這個賬戶的APP重新安裝的時候,添加的日程就全沒了,目前還不清楚什么原因,還是太菜雞 囧rz
- 獲取賬戶。返回值為-1表示當前沒有日歷賬戶
private int getSystemCalendarAccount(){
int account = -1;
Cursor userCursor = null;
try {
userCursor = mContext.getContentResolver().query(Uri.parse(CALANDER_URL), null, null, null, null);
if (userCursor != null && userCursor.getCount() > 0){
userCursor.moveToFirst();
account = userCursor.getInt(userCursor.getColumnIndex(CalendarContract.Calendars._ID));
}
}catch (Exception e){
e.printStackTrace();
}finally {
if (userCursor != null) {
userCursor.close();
}
}
return account;
}
- 新增一個賬戶。返回值為新增賬戶的id,-1表示創建失敗
private long setFoowwCalendar(){
ContentValues contentValues = new ContentValues();
// 日歷名稱
contentValues.put(CalendarContract.Calendars.NAME, CALENDARS_NAME);
// 日歷賬號,為郵箱格式
contentValues.put(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME);
// 賬戶類型,com.android.exchange
contentValues.put(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE);
// 展示給用戶的日歷名稱
contentValues.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CALENDARS_DISPLAY_NAME);
// 它是一個表示被選中日歷是否要被展示的值。
// 0值表示關聯這個日歷的事件不應該展示出來。
// 而1值則表示關聯這個日歷的事件應該被展示出來。
// 這個值會影響CalendarContract.instances表中的生成行。
contentValues.put(CalendarContract.Calendars.VISIBLE, 1);
// 賬戶標記顏色
contentValues.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.BLUE);
// 賬戶級別
contentValues.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER);
// 它是一個表示日歷是否應該被同步和是否應該把它的事件保存到設備上的值。
// 0值表示不要同步這個日歷或者不要把它的事件存儲到設備上。
// 1值則表示要同步這個日歷的事件并把它的事件儲存到設備上。
contentValues.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
// 時區
contentValues.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, TimeZone.getDefault().getID());
// 賬戶擁有者
contentValues.put(CalendarContract.Calendars.OWNER_ACCOUNT, CALENDARS_ACCOUNT_NAME);
contentValues.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 0);
Uri calendarUri = Uri.parse(CALANDER_URL);
calendarUri = calendarUri.buildUpon()
.appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME)
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE)
.build();
Uri result = mContext.getContentResolver().insert(calendarUri, contentValues);
return result == null ? -1 : ContentUris.parseId(result);
}
- 聯合1、2,檢查&創建&獲取賬戶
private int getAccount() {
int account = -1;
account = getSystemCalendarAccount();
if (account < 0){
return (int)setFoowwCalendar();
}
return account;
}
創建日歷事件
下面的 Schedule 是自定義的日程信息類
private Uri addCalendarEvent(Schedule schedule){
int account = getAccount();
if (account < 0)
return null;
ContentValues contentValues = new ContentValues();
// 事件的日歷_ID。
contentValues.put(CalendarContract.Events.CALENDAR_ID, account);
// 事件標題
contentValues.put(CalendarContract.Events.TITLE, schedule.getTitle());
// 事件發生的地點
contentValues.put(CalendarContract.Events.EVENT_LOCATION, schedule.getLocation());
// 事件描述
contentValues.put(CalendarContract.Events.DESCRIPTION, schedule.getDescription());
// 事件開始時間
contentValues.put(CalendarContract.Events.DTSTART, schedule.getStartTime());
// 事件結束時間
contentValues.put(CalendarContract.Events.DTEND, schedule.getEndTime());
// 設置有鬧鐘提醒
contentValues.put(CalendarContract.Events.HAS_ALARM, 1);
// 事件時區
contentValues.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
// 返回事件
return mContext.getContentResolver().insert(Uri.parse(CALANDER_EVENT_URL), contentValues);
}
創建日歷提醒
日歷提醒是基于日歷事件的,因此需要事件的url
private Uri addCalendarAlarm(Uri event){
// 事件提醒的設定
ContentValues contentValues = new ContentValues();
// 事件的ID
contentValues.put(CalendarContract.Reminders.EVENT_ID, ContentUris.parseId(event));
// 準時提醒 提前0分鐘提醒
contentValues.put(CalendarContract.Reminders.MINUTES, 0);
contentValues.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);
return mContext.getContentResolver().insert(Uri.parse(CALANDER_REMIDER_URL), contentValues);
}
添加日程
在獲取或者創建 賬戶,創建事件及事件提醒之后,就可以把日程添加到日歷中
如果添加失敗,還可以通過Intent打開日歷的添加界面讓用戶手動添加
public void insert(Schedule schedule){
try {
addCalendarAlarm(addCalendarEvent(schedule));
}catch (Exception e){
e.printStackTrace();
Intent intent = new Intent(Intent.ACTION_INSERT)
.setData(CalendarContract.Events.CONTENT_URI)
.putExtra(CalendarContract.Events.TITLE, schedule.getTitle())
.putExtra(CalendarContract.Events.DESCRIPTION, schedule.getDescription())
.putExtra(CalendarContract.Events.EVENT_LOCATION, schedule.getLocation())
.putExtra(CalendarContract.Events.DTSTART, schedule.getStartTime())
.putExtra(CalendarContract.Events.DTEND, schedule.getEndTime())
.putExtra(CalendarContract.Reminders.MINUTES, 0);
mContext.startActivity(intent);
}
}
結語
今天就先這樣把,剩下的刪除、修改、查詢之后和ContentResolver一起寫。