您的位置:首页 > 编程语言 > Go语言

Google Data API 使用体验 (1)-- Calendar篇

2010-07-27 22:08 525 查看
Google的API也出了有好久了..一直没用过..前段日子看到连GoogleCL这样的神器都出来了..想API应该已经比较完善了吧..就心痒痒一直想试试..咱有空也写个java版的GoogleCL出来..呵呵..一捱已经到了暑假..才研究了个calendar的简单使用..惭愧啊.
先上来记一笔..其实我个人一直很想先研究doc的..因为现有的客户端比较烂..想自己做个好用点的..但还是先搞了calendar..至于原因呢..在后面的几篇日志里应该会有个交代的..其实网上关于这些API研究的文已经很多了..写不写可能无所谓..但从我个人学习的经验总结下来..觉得弯路还是走的不少的..所以还是写一些心得出来比较好..(废话好多..)
以下为挑重点介绍下..原始的可以参看GoogleAPI..
例如:http://code.google.com/intl/zh-CN/apis/calendar/data/2.0/developers_guide_java.html
 
1.EventEntry元素
日历里的每个事件就是一个event..一般可以用一个EventEntry来表示..EventEntry主要有以下几个重要的属性:
1)PlainTextConstruct title
2)Person author
3)When time
4)Where location
5)PlainTextConstruct content
6)Recurrence recu
1)title顾名思义就是事件的名称或者说内容..可以是一个简单的String..
2)author是事件的作者..Person这个类中包含一个String的作者名字,还有Google帐号的username等信息..但实际上..我觉得可能是由于google服务本身的漏洞..这些信息都没有实际的作用..可以忽略不设也就是让他自动设置..
3)time也就是本次事件的起始时间.注意!:在一个Event里面只能有When或者Recurrence中的一个!如果是使用When..需要设置startTime和endTime这2个属性..他们都是DataTime类型的..也就是设置这个Event的起始和结束时间,并且这个Event显然是只执行一次的..如果你要添加的是一个周期性的Event..就不好用When了..需要使用Recurrence..这个后面再说..而这里的DataTime是需要这样形式的String来设置的:
例如:  2006-04-17T17:00:00-08:00
yyyy-MM-dd + "T" + hh:mm:ss + TimeZone
4)location即事件发生的地点..Where类也有rel/label/where三个String属性..同前所述..rel和label也不好用..可以不设..where就是你需要定义的地点..
5)content说明内容..即对本事件的补充信息..和title的使用方法相同.
6)recu...这是个好东西啊.花了我一个下午才大致研究出点眉目..说简单了..这就是用来设置事件的周期属性的..例如我每周一要上体育课..我只要生成一个上体育课的事件..然后设置Recurrence让他每周一都重复一次..还可以设置重复的次数或者截止日期..这样一学期的所有体育课就是一个Event了..而不是每周一节课都是一个Event..那样就要多出10多个Event了..而且不好管理..而要真正的掌握Recurrence的使用规则却不是很简单..这里先有个简单的映象..放到文末再详细介绍..
了解了这些元素..我们就可以根据需要来创建一个Event了..简单的代码如下:
public EventEntry createEventWhen(String title, String content, String author, String stime, String etime, String where) {
        EventEntry myEntry = new EventEntry();
        if (title != null) {
            myEntry.setTitle(new PlainTextConstruct(title));
        }
        if (content != null) {
            if (!content.startsWith(GCalendar.DefaultContentLabel)) {
                content = GCalendar.DefaultContentLabel + GCalendar.DefaultContentVersion + " " + content;
            }
            myEntry.setContent(new PlainTextConstruct(content));
        }
        if (author != null) {
            Person myAuthor = new Person(author, null, username);
            myEntry.getAuthors().add(myAuthor);
        }
        DateTime startTime = null;
        DateTime endTime = null;
        if (stime != null) {
            startTime = DateTime.parseDateTime(stime);//"2006-04-17T15:00:00-08:00"
        }
        if (etime != null) {
            endTime = DateTime.parseDateTime(etime);//"2006-04-17T17:00:00-08:00"
        }
        When eventTimes = new When();
        eventTimes.setStartTime(startTime);
        eventTimes.setEndTime(endTime);
        myEntry.addTime(eventTimes);
        if (where != null) {
            Where myWhere = new Where(GCalendar.DefaultWhereRel, GCalendar.DefaultWherelabel, where);
            myEntry.addLocation(myWhere);
        }
        return myEntry;
    }
 
public EventEntry createEventRecurrence(String title, String content, String author, String recu, String where) {
        EventEntry myEntry = new EventEntry();
        if (title != null) {
            myEntry.setTitle(new PlainTextConstruct(title));
        }
        if (content != null) {
            if (!content.startsWith(GCalendar.DefaultContentLabel)) {
                content = GCalendar.DefaultContentLabel + GCalendar.DefaultContentVersion + " " + content;
            }
            myEntry.setContent(new PlainTextConstruct(content));
        }
        if (author != null) {
            Person myAuthor = new Person(author, null, username);
            myEntry.getAuthors().add(myAuthor);
        }
        if (recu == null) {
            recu = new String("");
        }
        Recurrence rec = new Recurrence();
        rec.setValue(recu); 
        myEntry.setRecurrence(rec);
        //myEntry.addTime(null);

        if (where != null) {
            Where myWhere = new Where(GCalendar.DefaultWhereRel, GCalendar.DefaultWherelabel, where);
            myEntry.addLocation(myWhere);
        }
        return myEntry;
    }
 
2.CalendarService
1)创建CalendarService:
CalendarService myService = new CalendarService(GCalendar.CLIENTNAME);
其中GCalendar.CLIENTNAME可以是自己定义的客户端的名字..然后需要设置客户端相关:
myService.setProtocolVersion(CalendarService.Versions.V1);
这里我们选用的是v1也就是gdata-api 1.0的版本..其实2.0早就出来了..我所使用的lib也都是2.0的..但是也是由于google服务端的bug..2.0有很多的问题..我们只好先设置成1.0的才可以顺利的使用大部分功能..
2)设置Google帐号用户名和密码:
myService.setUserCredentials(username, password);
这一步不光会设置用户名和密码到客户端..还会自动网络验证..如果验证不通过..会抛出错误..
3)将Event添加到日历:EventEntry insertEvent(EventEntry entry)
URL postUrl= new URL(new String(GCalendar.DefaultURL).replaceFirst("username", username));
EventEntry insertedEntry = myService.insert(postUrl, entry);
entry即为要添加的EventEntry..GCalendar.DefaultURL =
http://www.google.com/calendar/feeds/username/private/full;
把这里的username部分用用户的邮件地址,例如:xxx@gmail.com替换后生成的URL即为用户的默认日历的feed地址...所以上述添加日历的过程实际上就是将要添加的EventEntry  POST 到用户日历的URL的过程..
4)查询日历事件:EventFeed queryEvent(String key)
Query myQuery=new Query(new URL(new String(GCalendar.DefaultURL).replaceFirst("username", username)));
myQuery.setMaxResults(max);//设置一次查找最大的返回条目数
myQuery.setFullTextQuery(key);//设置查找内容的关键字
EventFeed myFeed = myService.query(myQuery, EventFeed.class);
查找返回结果..myFeed.getEntries()即可得到一个符合查找条件的List..
5)更改日历事件:EventEntry updateEvent(EventEntry entry1, EventEntry entry2)
URL updateUrl= new URL(entry1.getEditLink().getHref());//entry1为要更改的event
updateEntry = myService.update(updateUrl, entry2);//entry2为更改后的event
6)删除日历事件:void deleteEvent(EventEntry entry)
URL deleteUrl = new URL(entry.getEditLink().getHref());//获得要删除的条目的link..
myService.delete(deleteUrl);//删除..
 
以上基本的函数应该就能满足简单的日历应用了..
 
补充(1):Recurrence规则的设置
关于Recurrence的定义可以参照 RFC2445
主要就是Recurrence有一个String value需要设置..
一个例子:
DTSTART;TZID=Asia/Shanghai:20100725T160000
DTEND;TZID=Asia/Shanghai:20100725T180000
RRULE:FREQ=WEEKLY;COUNT=10;INTERVAL=2;BYDAY=SU
上述所表达的规则的意思是:从上海时区的2010年7月25号16点开始到当日18点结束的一个事件,每隔一星期(即每2星期发生一次)的星期日重复一次事件,共发生10次.
DTATRT为事件开始的时间..DTEND为结束时间..TZID为时区的ID,可以通过
String TZID = TimeZone.getDefault().getID();来得到当前系统默认的时区的ID信息..RRULE是最重要的部分..决定事件的重复规律..
1)FREQ就是重复频率..YEARLY..MONTHLY..DAYLY等等..
2)可以是COUNT或者UNTIL..只可选其中一个..COUNT是事件总共发生的次数..UNTIL是周期时间结束的时间..他们决定了事件重复发生的结束条件..
3)附加选项信息..比如INTERVAL设定间隔..BYDAY按照一星期来设置重复的日子..详细的可以查看文档...呵呵..我这里简单能用就行了..
又一个例子:
DTSTART;TZID=Asia/Shanghai:20100725T160000
DURATION:3H
RRULE:FREQ=MONTHLY;UNTIL=20101010;INTERVAL=1;
上述所表达的意思是:从上海时区的2010年7月25号16点开始的事件,经历3个小时后结束,按照每月一次的频率重复发生直到2010年10月10号结束重复.
这里我们注意到用了DURATION这个选项来代替DTEND..意思应该是一目了然了吧..值的话可以是 3600S / 60M / 1H ..要注意的是两者只能选其一..即要么规定结束的时刻..要么规定时间持续的时间..
频率是每月一次..直到UNTIL所规定的日子结束..间隔为1..不规定BYDAY之类的重复日的话是按照重复频率和初始事件自动计算的..
以上..这2种基本的用法演示应该能满足简单使用需求了..
再讲一个小问题:即当FREQ选择的是MONTHLY按月重复的时候..假设我第一次事件是在1月31号..而2月只有28天或者29天..没有31天..那么按照正常的设置..是要2月31号才会重复触发事件..没有这一天的话就会自动忽略过去了..所以虽然设置的是按月重复..但实际上第二次发生是在3月31号了..同理..4月也不会发生..因为只有30天..那么就出现偏差了..假设我们的本意是要本月最后的一天发生的..每个月必须发生一次.那么..用如下的语句可以解决:
FREQ=MONTHLY;BYMONTHDAY=28,29,30;BYSETPOS=-1
奥妙就在这个BYSETPOS=-1..呵呵..大家都懂得吧..
 
以上..
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: