android对系统日历的读写操作开发经验的总结
这是我在做项目的时候总结的一些关于添加事件到系统日历的经验,希望对大家有所帮助,下面主要针对重复添加事件到日历进行分析,其中需要注意的事项。
- 首先就是要主要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 {
JSONObject resultObj=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来删除就可以了。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。