標籤:
這是我在做項目的時候總結的一些關於添加事件到系統日曆的經驗,希望對大家有所協助,下面主要針對重複添加事件到日曆進行分析,其中需要注意的事項。
- 首先就是要主要android中日曆的三個URL,分別是日曆URL,事件的URL,事件提醒URL,三個URL在android2.1之前是如下:
- calanderURL = "content://calendar/calendars";
- calanderEventURL = "content://calendar/events";
- calanderRemiderURL= "content://calendar/reminders";
但是在Android2.2版本之後,三個URL變成了如下:
- calanderURL = "content://com.android.calendar/calendars";
- calanderEventURL = "content://com.android.calendar/events";
- calanderRemiderURL = "content://com.android.calendar/reminders"
- 例如,你想添加一個簡單的提醒事件到系統日曆,該事件只對應一個提醒,你只要把一下這些設定進去就可以了,
Calendar cal = Calendar.getInstance();
args.put("dtstart", data.getDateTime() - 1);
String tt=Utils.getDateFmtFromTime(data.getDateTime());
args.put("dtend", data.getDateTime());
args.put("title", data.getRemindName());
args.put("description", data.getRemindName());
args.put("needStartApplication", false);
String result = CalendarUtil.addEvent(this, args);//添加到日曆
- 但是,當你添加一個事件,但這個事件對應多個提醒的時,需要重複添加到日曆裡面的時候,此時就需要用到Calendar中events表中的RRULE添加重複事件,此時這個RRULE規則對不同型號的手機,顯示的效果不一樣,RRule的格式://RFC-5545格式 freq=daily;byhour=8,13,18;byminute=0;bysecond=0;bydate=05 02,0922,一開始我使用RRule去重複添加事件到日曆裡面去,代碼如下:
args.put("dtend",entity.getEndTakeMedicineDate());
args.put("dtstart", entity.getStartTakeMedicineDate());
int days=ConvertUtil.compareDate(entity.getStartTakeMedicineDate(), entity.getEndTakeMedicineDate());
int countTime=(entity.getTakeMedicineCycle()+1)*days;
switch (i) {
case 0:
args.put("rrule", String.format("FREQ=YEARLY;COUNT=%s;BYHOUR=%s;BYMINUTE=%s",countTime,entity.getFirstTakeMedicineTime()[0],entity.getFirstTakeMedicineTime()[1]));
break;
case 1:
args.put("rrule", String.format("FREQ=YEARLY;COUNT=%s;BYHOUR=%s;BYMINUTE=%s",countTime,entity.getSecondTakeMedicineTime()[0],entity.getSecondTakeMedicineTime()[1]));
break;
case 2:
args.putcishi String.format("FREQ=YEARLY;COUNT=%s;BYHOUR=%s;BYMINUTE=%s",countTime,entity.getThirdTakeMedicineTime()[0],entity.getThirdTakeMedicineTime()[1]));
break;
default:
break;
}
args.put(Reminders.MINUTES, 5);
args.put("title", entity.getMedicineName());
args.put("description", String.format("%s%s%s%s",getString(R.string.the_one_day_take_medicine),entity.getTakeMedicineCycle()+1,getString(R.string.the_amount_of_time),entity.getNumOfEachTime()));
args.put("needStartApplication", false);
- 但是在三星的機型上顯示是正確的,在其他的機型都是有寫問題的,添加到日曆的條數和設定的條數不一致,還有時間有點混亂,可能是我寫的RRULE的格式寫錯了,在此希望有大神可以請教,對於這個問題是否有統一的RRule格式,在沒有找到同一的格式的情況下,我用了有點勉強的方法實現了功能,假如:要添加一個提醒,開始時間和結束時間隨便定,每天提醒的時間點也是隨使用者定的,假如有個人設定了從2015/5/19-2015/5/25每天上午09:00,下午04:30,由於用rrule規則添加到日曆顯示不正確,所以以下愛是我自己在項目中沒有用rrule規則的正確的方法,
for (int i = 0; i <entity.getTakeMedicineCycle()+1; i++) {
JSONObject args=new JSONObject();
//TODO 構建標準參數
try {
long startTime=entity.getStartTakeMedicineDate();//開始的日期
long endTime= entity.getEndTakeMedicineDate();//結束 的日期
switch (i) {
case 0:
//把開始提醒的日期和時間用Calendar組合起來
Calendar startTakeTime1=Calendar.getInstance();
startTakeTime1.setTimeInMillis(startTime);
startTakeTime1.set(Calendar.HOUR, entity.getFirstTakeMedicineTime()[0]);//開始的時間點
startTakeTime1.set(Calendar.MINUTE, entity.getFirstTakeMedicineTime()[1]);//開始的分鐘
Calendar endTakeTime1=Calendar.getInstance();
endTakeTime1.setTimeInMillis(endTime);
endTakeTime1.set(Calendar.HOUR, entity.getFirstTakeMedicineTime()[0]);
endTakeTime1.set(Calendar.MINUTE, entity.getFirstTakeMedicineTime()[1]);
args.put("dtstart", startTakeTime1.getTimeInMillis());
args.put("dtend",endTakeTime1.getTimeInMillis());
args.put("dtend",endTakeTime1.getTimeInMillis());
break;
case 1:
Calendar startTakeTime2=Calendar.getInstance();
startTakeTime2.setTimeInMillis(startTime);
startTakeTime2.set(Calendar.HOUR, entity.getSecondTakeMedicineTime()[0]);
startTakeTime2.set(Calendar.MINUTE, entity.getSecondTakeMedicineTime()[1]);
Calendar endTakeTime2=Calendar.getInstance();
endTakeTime2.setTimeInMillis(endTime);
endTakeTime2.set(Calendar.HOUR, entity.getSecondTakeMedicineTime()[0]);
endTakeTime2.set(Calendar.MINUTE, entity.getSecondTakeMedicineTime()[1]);
args.put("dtstart", startTakeTime2.getTimeInMillis());
args.put("dtend",endTakeTime2.getTimeInMillis());
break;
case 2:
String thrid=String.format("%s:%s", entity.getThirdTakeMedicineTime()[0],entity.getThirdTakeMedicineTime()[1]);
Calendar startTakeTime3=Calendar.getInstance();
startTakeTime3.setTimeInMillis(startTime);
startTakeTime3.set(Calendar.HOUR, entity.getThirdTakeMedicineTime()[0]);
startTakeTime3.set(Calendar.MINUTE, entity.getThirdTakeMedicineTime()[1]);
Calendar endTakeTime3=Calendar.getInstance();
endTakeTime3.setTimeInMillis(endTime);
endTakeTime3.set(Calendar.HOUR, entity.getThirdTakeMedicineTime()[0]);
endTakeTime3.set(Calendar.MINUTE,entity.getThirdTakeMedicineTime()[1]);
args.put("dtstart", startTakeTime3.getTimeInMillis());
args.put("dtend",endTakeTime3.getTimeInMillis());
break;
default:
break;
}
args.put(Reminders.MINUTES, 5);//提醒5分鐘有提醒
args.put("title", entity.getMedicineName());
args.put("description", String.format("%s%s%s%s",getString(R.string.the_one_day_take_medicine),entity.getTakeMedicineCycle()+1,getString(R.string.the_amount_of_time),entity.getNumOfEachTime()));
args.put("needStartApplication", false);
//添加事件到日曆
String result=CalendarUtil.addEvent(context, args);
}
/**
* 增加事件到日曆
*
* @param context
* @param args
* 參數
*/
public static String addEvent(Context context, JSONObject args) {
String result = null;
if(args!=null){
long calendarId = getCalendarId(context);
if (calendarId == -1) {
// no calendar account; react meaningfully
return null;
}
ContentValues values = new ContentValues();
long startTime=System.currentTimeMillis();
if(args.has("dtstart")){
startTime = Long.valueOf(JSONUtil.getJSONObjectValue(args, "dtstart").toString());
values.put("dtstart", startTime);
}
long endTime=-1;
if (args.has("dtend")) {
endTime = Long.valueOf(JSONUtil.getJSONObjectValue(args, "dtend").toString());
values.put("dtend", endTime);
}
// 添加事件
if(args.has("rrule")){
String id=Events._ID;
values.put("rrule", JSONUtil.getJSONObjectValue(args, "rrule").toString());
}
if(args.has("duration")){
values.put("duration", JSONUtil.getJSONObjectValue(args, "duration").toString());
}
values.put(Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
values.put(Events.EVENT_END_TIMEZONE, TimeZone.getDefault().getID());
if(args.has("title")){
values.put("title", JSONUtil.getJSONObjectValue(args, "title").toString());
}
values.put(Events.CALENDAR_ID, calendarId);
if(args.has("description")){
values.put("description",JSONUtil.getJSONObjectValue(args,"description").toString());
}
Uri uri = context.getContentResolver().insert(Uri.parse(calanderEventURL), values);
long eventId = Long.valueOf(uri.getLastPathSegment());
values.clear();
// 添加提醒
values.put(Reminders.EVENT_ID, eventId);
if(args.has(Reminders.MINUTES)){
String id=Reminders._ID;
values.put(Reminders.MINUTES,JSONUtil.getJSONObjectValue(args, Reminders.MINUTES).toString());
}
values.put(Reminders.METHOD, Reminders.METHOD_ALERT);
Uri reminderUri = context.getContentResolver().insert(Uri.parse(calanderRemiderURL), values);
long reminderId = Long.valueOf(reminderUri.getLastPathSegment());
if(reminderId>0){
if(args.has("needStartApplication")){
boolean needStartApplication=Boolean.valueOf(JSONUtil.getJSONObjectValue(args, "needStartApplication").toString());
if(needStartApplication){
FZZSApplication.getInstance().toOtherActivity(context, Constants.TO_REMIND_TO_SPLASH_ACTIVITY, endTime);
}
}
try {
JSONObjectresultObj=new JSONObject();
resultObj.put("calendarId", calendarId);
resultObj.put("eventId", eventId);
resultObj.put("reminderId", reminderId);
result=resultObj.toString();//把三個Id返回
} catch (Exception e) {
}
}
}
return result;
}
- 這樣就成功添加到系統日曆裡面去了。對於添加,主要是只是針對添加重複事件要注意,因為那個RRULE格式有點難掌握,不過也可以不用系統定的rrule規則,而像我那樣組合重複添加。還有對於重複資料刪除添加的事件,一個事件對應多個提醒,他的eventId不止一個,而是一個提醒對應一個eventId,如果要想刪除添加到日曆的重複事件,就要把每個eventId儲存起來,這樣在迴圈根據eventId來刪除就可以了。
android對系統日曆的讀寫操作開發經驗的總結