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

来源:互联网 发布:淘宝上可靠的种子店 编辑:程序博客网 时间:2024/05/16 17:10

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..呵呵..大家都懂得吧..

 

以上..

原创粉丝点击