jizzjizz亚洲,亚洲mv国产精品mv日本mv,亚洲av无码潮喷在线观看http://m.tkk7.com/zhenandaci/category/37468.html嘉士伯的Java小屋zh-cnMon, 09 Mar 2009 17:28:56 GMTMon, 09 Mar 2009 17:28:56 GMT60Google Gadget 開(kāi)發(fā)入門(六)界面二三事http://m.tkk7.com/zhenandaci/archive/2009/02/10/254135.htmlJasperJasperTue, 10 Feb 2009 14:05:00 GMThttp://m.tkk7.com/zhenandaci/archive/2009/02/10/254135.htmlhttp://m.tkk7.com/zhenandaci/comments/254135.htmlhttp://m.tkk7.com/zhenandaci/archive/2009/02/10/254135.html#Feedback0http://m.tkk7.com/zhenandaci/comments/commentRss/254135.htmlhttp://m.tkk7.com/zhenandaci/services/trackbacks/254135.html

目前為止不管后臺(tái)寫了多少邏輯(已經(jīng)登錄了Google,取了相冊(cè)數(shù)據(jù)),我們的Gadget都還是那個(gè)看上去白白的Gadget。而要想讓它看上去有所不同,就要在main.xml這個(gè)文件中,制定我們想要的“長(zhǎng)相”(就跟征婚啟事里寫的一樣,身高1617,體重不超過(guò)55公斤,相貌端正,賢良淑惠)。

如果你已經(jīng)下載了我提供的源碼,就可以打開(kāi)看看,對(duì)照實(shí)際效果來(lái)看代碼,應(yīng)該很好理解。我們總計(jì)在界面上放了幾樣?xùn)|西:

  •  一張背景圖(就是白白的那個(gè))
  •  一張PicasaLogo
  •  兩行表示歡迎的文字(就是label啦)
  •  一個(gè)用來(lái)顯示相冊(cè)信息的列表(listbox),當(dāng)然,目前列表中還一個(gè)列表項(xiàng)都沒(méi)有(列表項(xiàng)稱之為item
  •  最后又貼了兩張圖,其中一張是某企業(yè)的logo(笑)

其中值得注意的事情有這么幾件:

一是背景圖片絕非可有可無(wú),按google的說(shuō)法,像label這種東西,如果沒(méi)有放在一張背景圖片之上的話,是顯示不出來(lái)的。

二是Gadget中界面的內(nèi)容,樣式和布局都在這一個(gè)文件中指定。

三是Gadget的界面沒(méi)有HTML那種流動(dòng)布局的效果,就是說(shuō),所有要顯示的元素,必須明明白白的指出它的位置,也就是每個(gè)元素的xy屬性,是從該元素的父元素左上角開(kāi)始計(jì)算的坐標(biāo)。如果你先寫了一個(gè)label(拿label舉個(gè)例子,實(shí)際上用什么效果都是一樣的),再挨著它寫了一個(gè)label,兩個(gè)label你都沒(méi)有指定xy的值,那么這個(gè)兩個(gè)label會(huì)重疊著顯示在一起。不信你可以試一試。

四是圖片的源文件位置,從代碼中可以看到指定本機(jī)上的相對(duì)目錄是可以的,那么指定一個(gè)網(wǎng)絡(luò)上的url可以么?例如http://www.sina.com.cn/images/logo.gif?如果你頭腦中還存在著HTML的印象,可能想當(dāng)然的以為可以這么做,而事實(shí)上不行,GadgetWeb沒(méi)有天然的聯(lián)系(沒(méi)記錯(cuò)的話,我已經(jīng)說(shuō)過(guò)四次了)。后面處理相冊(cè)縮略圖的時(shí)候,我們會(huì)看到怎么把網(wǎng)絡(luò)上的圖片顯示出來(lái)。

寫過(guò)圖形用戶界面程序的人一定想問(wèn),如何讓界面上的元素與代碼產(chǎn)生聯(lián)系呢?例如我們的列表,我想在代碼中對(duì)它作些修改的時(shí)候,如何取得它的引用呢?在Gadget中這一點(diǎn)還比較方便,主要有兩個(gè)途徑:一是只要你給元素賦了name屬性,例如我就給列表項(xiàng)起了一個(gè)名字叫做contentListBox,在main.xml中的這一行:

<listbox height="130" name="contentListBox" width="200" x="25" y="100"

 

之后就可以直接在代碼中用contentListBox這個(gè)值來(lái)訪問(wèn)這個(gè)列表項(xiàng)了(而且任你在代碼中怎么找,也找不到聲明或者初始化這個(gè)變量的地方)——當(dāng)然前提是起的名字必須是唯一的。有意思吧?

第二種方式比較傳統(tǒng)也比較少用,可以通過(guò)DOM對(duì)象訪問(wèn)每個(gè)元素。

廢話不多說(shuō),來(lái)看看在代碼中給列表插入列表項(xiàng)怎么做。

列表項(xiàng)對(duì)應(yīng)著Gadget API提供的一個(gè)名為item的對(duì)象實(shí)例,但我們要用new item()這樣的語(yǔ)法來(lái)得到一個(gè)新的列表項(xiàng)并逐一設(shè)置它的屬性么?不不,有更簡(jiǎn)便也更好玩的方法,我們只要新建一個(gè)字符串:


var itemXml= '<item name="album_item"><label>列表項(xiàng)</label></item>';

然后調(diào)用列表contentListBox的方法來(lái)添加就可以,像這樣:

var newItem = contentListBox.appendElement(itemXml);

方便么?這種用法使得開(kāi)發(fā)人員不需要為一個(gè)圖形界面的組件掌握兩套語(yǔ)法(XML的和JavaScript的),非常貼心。

好,現(xiàn)在來(lái)說(shuō)另一個(gè)問(wèn)題,既然不能為一個(gè)img對(duì)象的src屬性指定一個(gè)網(wǎng)絡(luò)地址,那到底如何顯示網(wǎng)絡(luò)上的圖片呢?答案很長(zhǎng),如果你有了圖片的url(就是 http://開(kāi)頭的那種啦),首先要通過(guò)XmlHttpRequest把圖片的數(shù)據(jù)取回來(lái),然后把這部分?jǐn)?shù)據(jù)賦給src屬性。

具體點(diǎn),記得一個(gè)請(qǐng)求最重要的四部分?jǐn)?shù)據(jù)么?url:就是該圖片的url;請(qǐng)求類型:因?yàn)槭且髷?shù)據(jù),自然是“GET”;請(qǐng)求頭:對(duì)本請(qǐng)求來(lái)說(shuō)沒(méi)有;消息體:同樣沒(méi)有。

所以發(fā)請(qǐng)求的部分并不困難,待請(qǐng)求的狀態(tài)變?yōu)?/span>4,也就是說(shuō)明回傳數(shù)據(jù)已到達(dá)的時(shí)候,就可以從請(qǐng)求的responseStream這個(gè)屬性得到圖片的二進(jìn)制數(shù)據(jù)。假設(shè)在代碼中我們要顯示的圖片是<img name=”myImg”/>,記得么,使用名字可以直接訪問(wèn)這個(gè)圖片,再假設(shè)我們的請(qǐng)求對(duì)象取名為xhRequest,像下面這樣:

myImg.src=xhRequest. responseStream;

如此就可以了!哈哈,簡(jiǎn)單吧(我當(dāng)初倒是找了半天,讀過(guò)了YouTube Gadget的代碼才參透呢,愚笨愚笨)。

在我們剩下的唯一一個(gè)重要函數(shù)MainfetchAlbumThumbnail()中,就是使用這種方法來(lái)取得相冊(cè)縮略圖的圖片并顯示在Gadget的界面中的。

這個(gè)函數(shù)我就不逐一分解了,相信你一定看得懂。



Jasper 2009-02-10 22:05 發(fā)表評(píng)論
]]>
Google Gadget開(kāi)發(fā)入門(五)Gadget中從Picasa取得相冊(cè)數(shù)據(jù)http://m.tkk7.com/zhenandaci/archive/2009/02/10/254110.htmlJasperJasperTue, 10 Feb 2009 09:28:00 GMThttp://m.tkk7.com/zhenandaci/archive/2009/02/10/254110.htmlhttp://m.tkk7.com/zhenandaci/comments/254110.htmlhttp://m.tkk7.com/zhenandaci/archive/2009/02/10/254110.html#Feedback0http://m.tkk7.com/zhenandaci/comments/commentRss/254110.htmlhttp://m.tkk7.com/zhenandaci/services/trackbacks/254110.html

大的方向上說(shuō),從Picasa服務(wù)器上取數(shù)據(jù),有兩種方式,一種是使用Google已經(jīng)開(kāi)放的各種語(yǔ)言的API,可以在頁(yè)面http://code.google.com/apis/picasaweb/developers_guide_protocol.html找到很多相關(guān)的信息。另一種方式便是使用最樸素的網(wǎng)絡(luò)請(qǐng)求方式來(lái)自己構(gòu)造請(qǐng)求并解析回傳的數(shù)據(jù)。

由于Picasa只提供了Java,.NET,Python和PHP的接口,而Gadget目前只能使用JavaScript,因此我們只能使用樸素方式。

繼續(xù)第三節(jié)的路子,仍然使用XmlHttpRequest向Picasa服務(wù)發(fā)起請(qǐng)求,也要處理好四部分信息。

請(qǐng)求發(fā)向哪個(gè)URL為了獲取Picasa的相冊(cè)信息,要向http://picasaweb.google.com/data/feed/api/user/default發(fā)請(qǐng)求,這個(gè)URL其實(shí)可以有很多變化的地方。例如user/default這個(gè)地方是請(qǐng)求所附token所屬的用戶相冊(cè)信息,這里當(dāng)然可以明確的指定用戶名。”api”可以換成”base”,這個(gè)將影響回傳數(shù)據(jù)的格式,但Goolge推薦使用api而不是base。

請(qǐng)求的類型:我們是要索取數(shù)據(jù),因此這是一個(gè)查詢的動(dòng)作,應(yīng)該使用GET。

請(qǐng)求頭:只需要把token放進(jìn)去就好。這樣來(lái)放:

xhRequest.setRequestHeader('Authorization','GoogleLogin auth=+ token);

消息體:對(duì)于我們查詢相冊(cè)的請(qǐng)求,不需要任何的消息體。

具體的代碼都在Main.prototype.fetchAlbumsInfo()函數(shù)中,就像這樣:


Main.prototype.fetchAlbumsInfo=function() {
    
var url="http://picasaweb.google.com/data/feed/api/user/default";
    
var token=options.getValue("token");
    xhRequest
= createXhr();
    xhRequest.open(
"GET", url, true);
    xhRequest.setRequestHeader('Authorization','GoogleLogin auth
=+ token);
    xhRequest.send(
null);
    xhRequest.onreadystatechange 
=function(){
        
if (!xhRequest) {
            
return;
        }
        
if (xhRequest.readyState != 4) {
            
return;
        }
        main.albums
=parseAlbumFeed(xhRequest.responseText);
        main.fetchAlbumThumbnail();
    }
};

最后兩個(gè)函數(shù)是下一步要做的工作:解析回傳的相冊(cè)數(shù)據(jù),并下載每個(gè)相冊(cè)的縮略圖。

 

要想解析回傳數(shù)據(jù),首先得知道回傳的數(shù)據(jù)是什么。你可以把這些數(shù)據(jù)打印出來(lái)看看,應(yīng)該是類似下面的樣子:

clip_image001

怎么,看著有點(diǎn)眼熟?沒(méi)錯(cuò),這個(gè)回傳數(shù)據(jù)所使用的格式正是標(biāo)準(zhǔn)的Atom Feed(更多的描述可以參考W3C的標(biāo)準(zhǔn)和下面的鏈接:http://code.google.com/intl/zh-CN/apis/picasaweb/developers_guide_protocol.html)。

可以根據(jù)Atom Feed的格式來(lái)編寫我們解析回傳數(shù)據(jù)的函數(shù)parseAlbumFeed(),這個(gè)函數(shù)的作用是從回傳的xml數(shù)據(jù)中找出我們關(guān)心的幾樣?xùn)|西:該用戶目前擁有的所有的相冊(cè)信息,包括每個(gè)相冊(cè)的標(biāo)題,描述,訪問(wèn)權(quán)限以及縮略圖的地址。找出這些信息以后,將會(huì)拼成一個(gè)包含相冊(cè)(Album)的數(shù)組作為函數(shù)返回值。

具體代碼如下:


function parseAlbumFeed(response) {
  
var doc = createDomDocument();
  doc.loadXML(response);
  
  
//用戶已經(jīng)建立過(guò)的相冊(cè)集合,函數(shù)的返回值
  var albums = [];

  
var entryElements = doc.getElementsByTagName('entry');
  
//具體處理每個(gè)Album的信息
  for (var i = 0; i < entryElements.length; i++) {
    
var entry = entryElements[i];
    
var album=new Album();

    
//相冊(cè)標(biāo)題
    album.title=entry.getElementsByTagName('title')[0].text;

    
//相冊(cè)描述
    album.summary=entry.getElementsByTagName('summary')[0].text;

    
//相冊(cè)的訪問(wèn)權(quán)限
    album.access=entry.getElementsByTagName('gphoto:access')[0].text;

    
//相冊(cè)的縮略圖
    var thumbnail=entry.getElementsByTagName('media:thumbnail')[0];
    album.thumbnail
=new Thumbnail(thumbnail.getAttribute('url'));
    albums.push(album);
  }

  
return albums;
};

這個(gè)函數(shù)中用到了一些我們還沒(méi)有新建的類,相冊(cè)(Album)以及縮略圖(Thumbnail)。這些類的聲明可以放在一個(gè)新的名為album.js的文件中,并在我們整個(gè)Gadget的main.xml文件中指名要導(dǎo)入它。因此main.xml的最后幾行應(yīng)該看上去是這個(gè)樣子:


  <script src="album.js" />
  
<script src="main.js" />
</view>

而album.js的內(nèi)容大體如下:


function Album() {
  
this.title = "";
  
this.summary="";
  
this.access="";
  
this.thumbnail=#ff0000;
}

function Thumbnail(url) {
  
this.url = url;
  
this.width = 40;
  
this.height = 40;
  
this.src = undefined;  // XML response stream
}

最后還要在main.js里面添加一個(gè)函數(shù)createDomDocument(),用來(lái)提供一個(gè)DOM對(duì)象供我們解析XML用。代碼如下:


function createDomDocument() {
  
var doc = new DOMDocument();

  
try {
    doc.resolveExternals 
= false;
    doc.validateOnParse 
= false;
    doc.setProperty('ProhibitDTD', 
false);
  } 
catch(e) {
    debug.warning('Could not set MS specific properties.');
  }
  
return doc;
}

下一節(jié)來(lái)說(shuō)說(shuō)怎么取得相冊(cè)的縮略圖并顯示在Gadget的界面中。



Jasper 2009-02-10 17:28 發(fā)表評(píng)論
]]>
Google Gadget開(kāi)發(fā)入門(四)處理tokenhttp://m.tkk7.com/zhenandaci/archive/2009/02/06/253594.htmlJasperJasperFri, 06 Feb 2009 08:35:00 GMThttp://m.tkk7.com/zhenandaci/archive/2009/02/06/253594.htmlhttp://m.tkk7.com/zhenandaci/comments/253594.htmlhttp://m.tkk7.com/zhenandaci/archive/2009/02/06/253594.html#Feedback0http://m.tkk7.com/zhenandaci/comments/commentRss/253594.htmlhttp://m.tkk7.com/zhenandaci/services/trackbacks/253594.html

Google的服務(wù)器發(fā)起登錄請(qǐng)求之后,得到了免死金牌token,以后就可以拿著這個(gè)token去犯罪,不是,去Google的其它服務(wù)取數(shù)據(jù),但是在此之前應(yīng)該第一,從響應(yīng)的消息中把token找出來(lái);第二,這個(gè)token應(yīng)該想辦法保存起來(lái),以備以后使用。

上一節(jié)已經(jīng)把響應(yīng)的內(nèi)容打印了出來(lái),它的格式也很簡(jiǎn)單,因此用下面的代碼很容易就可以把響應(yīng)的內(nèi)容轉(zhuǎn)成方便我們使用的形式,即一個(gè)map的形式,通過(guò)鍵值對(duì)來(lái)存儲(chǔ):


function parseResponse(response) {

 
var responseLines = response.split('\n');

 var responseData = {};

 for (var i = 0; i < responseLines.length; ++i) {

    var split = responseLines[i].indexOf('=');

    var key = responseLines[i].substr(0, split);

    var value = responseLines[i].substr(split + 1);

    responseData[key] = value;

 }

 return responseData;

};

在我們的相應(yīng)回調(diào)函數(shù)里,就可以調(diào)用這個(gè)函數(shù)處理一下響應(yīng),從結(jié)果中取鍵為”Auth”這一項(xiàng)的值,并保存在Gadget Host為我們準(zhǔn)備好的一個(gè)負(fù)責(zé)持久化的對(duì)象options中。找到上一節(jié)Main.prototype.login的代碼,把響應(yīng)的回調(diào)函數(shù)改成下面的樣子:


xhRequest.onreadystatechange =function(){

           
if (!xhRequest) {

                 
return;

           }

           
if (xhRequest.readyState != 4) {

                 
return;

           }

           
//調(diào)用新寫的函數(shù)來(lái)解析響應(yīng)內(nèi)容

var responseData = parseResponse(xhRequest.responseText);

           
var token = responseData['Auth'];

           
//這里來(lái)記住已經(jīng)登錄過(guò)的用戶名和密碼

           options.putValue(
"username","mymail2009.test@gmail.com");

           options.putValue(
"password","mymail2009");

           options.putValue(
"token", token);

           options.encryptValue(
"token");

           main.onLoginSuccess();

}

最后加的一行main.onLoginSuccess()就是我們下一步動(dòng)作的起點(diǎn),在這里應(yīng)該開(kāi)始去取用戶mymail2009.test@gmail.com所擁有的相冊(cè)信息了,我們先聲明一個(gè)空函數(shù)放在那里。


Main.prototype.onLoginSuccess=function(){

  
this.fetchAlbumsInfo();

};

//取相冊(cè)信息的函數(shù)

Main.prototype.fetchAlbumsInfo
=function() {

};

繼續(xù)之前多扯兩句options這個(gè)對(duì)象,這是Gadget Host提供的持久化對(duì)象,你可以從代碼中看到它還有對(duì)存儲(chǔ)的內(nèi)容進(jìn)行加密的功能,Google的文檔中提到這個(gè)options對(duì)象在后臺(tái)實(shí)際上是把內(nèi)容保存在一個(gè)XML文件中,當(dāng)然該文件的位置是不會(huì)告訴你的啦,哈哈。

下一節(jié)將向Picasa服務(wù)發(fā)起請(qǐng)求!



Jasper 2009-02-06 16:35 發(fā)表評(píng)論
]]>
Google Gadget開(kāi)發(fā)入門(三)在Gadget中做Google帳戶的登錄http://m.tkk7.com/zhenandaci/archive/2009/02/06/253579.htmlJasperJasperFri, 06 Feb 2009 07:51:00 GMThttp://m.tkk7.com/zhenandaci/archive/2009/02/06/253579.htmlhttp://m.tkk7.com/zhenandaci/comments/253579.htmlhttp://m.tkk7.com/zhenandaci/archive/2009/02/06/253579.html#Feedback0http://m.tkk7.com/zhenandaci/comments/commentRss/253579.htmlhttp://m.tkk7.com/zhenandaci/services/trackbacks/253579.html

Google帳戶最早用來(lái)申請(qǐng)巨大的Gmail郵箱(如今看來(lái),一般個(gè)大吧),隨著后來(lái)的BloggerPicasaDocs等各種服務(wù)上線,也就順路繼承了過(guò)來(lái)。現(xiàn)在使用一個(gè)Google帳戶,就可以同時(shí)使用這些服務(wù)。

既然我們打算寫一個(gè)從Picasa取相冊(cè)數(shù)據(jù)的Gadget,就免不了要先了解一些和Goolge帳戶有關(guān)的知識(shí)。因?yàn)?/span>Picasa的數(shù)據(jù)也是受保護(hù)的,并非誰(shuí)要看都可以(公開(kāi)的相冊(cè)除外哦,那都是炫耀冊(cè),巴不得全天下人都看見(jiàn)呢),我們的程序也不例外,要想取到相冊(cè)的數(shù)據(jù),程序必須向Google的服務(wù)器證明自己得到了相應(yīng)用戶的授權(quán)。

一個(gè)人類用戶當(dāng)然可以這樣做:打開(kāi)Picasa的首頁(yè),發(fā)現(xiàn)要求登錄,于是輸入自己的用戶名密碼,成功后就查看自己的相冊(cè)。我們的程序可干不了,它不會(huì)打開(kāi)瀏覽器,好吧,這個(gè)它會(huì),但打開(kāi)以后它找不著用戶名的輸入框在哪,即便找到了,也不知該往里面填什么,即便填對(duì)了,也不知要看什么,即便看到了,也看不懂,即便看懂了也學(xué)不會(huì)……(讀者:你貧不貧?)

所以一切的一切都還要咱們自己來(lái)寫,當(dāng)然少不了Google的幫忙。

為了方便應(yīng)用程序的登錄,Google在自己的服務(wù)器上開(kāi)放了被稱之為“Google Account Authentication”的服務(wù),我們只用到其中一種方式:ClientLogin。使用這種方式訪問(wèn)Google的服務(wù)大致是下面的流程:


很容易看出來(lái),這基本上是一個(gè)兩步驟的工作:首先使用一個(gè)Google帳戶訪問(wèn)Google Account Authentication 服務(wù),并得到一個(gè)可以合法訪問(wèn)服務(wù)數(shù)據(jù)的tokenGoogle把它叫做得到一個(gè)“授權(quán)”,不過(guò)習(xí)慣上還是叫token吧,就是令牌,拿了以后皇帝不能砍你頭的那種,此過(guò)程也叫做申請(qǐng)一個(gè)token);使用上一步得到的token去訪問(wèn)具體的服務(wù)并取得數(shù)據(jù)(我們的例子中就是訪問(wèn)Picasa服務(wù))。

有一些東西從圖上看不出,我來(lái)說(shuō)一說(shuō)。一是程序訪問(wèn)Gmail的時(shí)候使用的不是這種方式(畢竟Gmail太早啦,那時(shí)連Google自己都沒(méi)有考慮清楚吧),但其他大部分Goolge服務(wù),包括Calendar,Docs,Picasa,Blogger,Contacts,Google Apps等等,都是上面這個(gè)流程。二是并非申請(qǐng)了一個(gè)token以后,就可以訪問(wèn)Google所有的服務(wù),實(shí)際上需要為每個(gè)服務(wù)申請(qǐng)不同的token

具體到代碼中,我們使用XmlHttpRequest對(duì)象來(lái)發(fā)送請(qǐng)求并且接受回傳的數(shù)據(jù)。

XmlHttpRequestGadget Host提供的一個(gè)類型(注意我沒(méi)有說(shuō)對(duì)象,因此要用的時(shí)候你還得自己初始化,也就是new一下,哈哈),其行為與W3C所指定的標(biāo)準(zhǔn)XmlHttpRequest相同。再一次的,不要聯(lián)想到瀏覽器,你不能假設(shè)這個(gè)XmlHttpRequestIE或者FireFox提供的XmlHttpRequest有任何聯(lián)系,更不能依賴這樣的假設(shè)來(lái)編寫程序。

好,廢話少說(shuō),還用上一節(jié)新建的“白Gadget“(笑),在main.js文件里添加這樣一個(gè)函數(shù):


function createXhr() {

 
var xhr;

 
try {

    xhr 
= framework.google.betaXmlHttpRequest2();

 } 
catch (e) {

    xhr 
= new XMLHttpRequest();

 }

 
return xhr;

}

調(diào)用這個(gè)函數(shù)就可以得到一個(gè)XmlHttpRequest的對(duì)象啦。

然后為我們的Gadget添加一個(gè)主類,并把需要的對(duì)象引用也聲明好,這些都寫在main.js文件中,像這樣:


var xhRequest=null;

var main=new Main();

      
//Gadget啟動(dòng)時(shí)便登錄

function view_onOpen() {

            main.login();

}

function Main(){

            
this.albums=[];

}

//具體的登錄函數(shù)

Main.prototype.login
=function(){

}

我們就要在Main.login()函數(shù)中寫我們?nèi)?/span>token的邏輯。

詳細(xì)說(shuō)說(shuō)申請(qǐng)token的過(guò)程。請(qǐng)求是通過(guò)XmlHttpRequest對(duì)象發(fā)起的,而對(duì)一個(gè)請(qǐng)求來(lái)說(shuō),最重要的信息有四個(gè):請(qǐng)求的URL,請(qǐng)求的類型,請(qǐng)求頭和消息體。

URL是說(shuō)你的請(qǐng)求要發(fā)往哪里,既然我們要使用Google的服務(wù),那當(dāng)然要往Google那里發(fā)了,具體應(yīng)該為:

https://www.google.com/accounts/ClientLogin

如果你沒(méi)有看出這是一個(gè)安全的https請(qǐng)求,那我提醒一下(如果你看出來(lái)了,我就不提醒了,笑)。

請(qǐng)求的類型是指你要Google的服務(wù)器替你做什么事情,是返回你要查詢的數(shù)據(jù)?還是為你更新已有的數(shù)據(jù),抑或僅僅是提交一些數(shù)據(jù),還是要服務(wù)器幫你刪除一些數(shù)據(jù)?

Google的服務(wù)器通過(guò)你提交請(qǐng)求的類型來(lái)做相應(yīng)的操作,每一種操作的類型對(duì)應(yīng)如下:

  •  查詢  GET
  •  提交  POST
  •  更新  PUT
  •  刪除  DELETE

看著眼熟么?沒(méi)錯(cuò),正是輕量級(jí)的Web Service接口REST

我們做登錄顯然是一個(gè)提交的動(dòng)作, 要把我們的用戶名和密碼告訴Google因此我們的請(qǐng)求類型是POST

對(duì)登錄來(lái)說(shuō),請(qǐng)求頭沒(méi)有特殊要求,只需要請(qǐng)求頭Content-Type其值為application/x-www-form-urlencoded

所需的用戶名,密碼等信息被統(tǒng)一稱為“屬性”,屬性的值將放在消息體中發(fā)送。因此你的消息體看起來(lái)是下面這個(gè)樣子的一個(gè)字符串:

Email=mymail2009.test%40gmail.com&Passwd=mymail2009&service=lh2&source=gd-picasa-gadget-1.0.0.0&accountType=HOSTED_OR_GOOGLE

注意其中紅色的部分,用戶名和密碼的位置你當(dāng)然很容易找到,service=lh2這一項(xiàng)就指明了你要為訪問(wèn)什么服務(wù)申請(qǐng)tokenlh2是指Picasa,如果訪問(wèn)Google Docs則要填writely,詳細(xì)的列表可以看這一節(jié)最后的附錄。

好,把登錄的代碼整個(gè)貼出來(lái),你應(yīng)該很容易找到以上四部分對(duì)應(yīng)的地方。


Main.prototype.login=function(){

      xhRequest
= createXhr();

      
//請(qǐng)求的URL

      
var url="https://www.google.com/accounts/ClientLogin";

      
//消息體

      
var data="Email=mymail2009.test%40gmail.com&Passwd=mymail2009&service=lh2&source=gd-picasa-gadget-1.0.0.2&accountType=HOSTED_OR_GOOGLE";

      xhRequest.onreadystatechange 
=function(){

           
if (!xhRequest) {

                 
return;

           }

           
if (xhRequest.readyState != 4) {

                 
return;

           }

           
//如果下面這行能夠被執(zhí)行,說(shuō)明登錄請(qǐng)求已經(jīng)有數(shù)據(jù)返回

           alert(“登錄動(dòng)作完畢啦!”);

           alert(xhRequest.responseText);

      }
//接受數(shù)據(jù)后的回調(diào)函數(shù)

      
//請(qǐng)求的類型,是POST

      xhRequest.open('POST', url, 
true);

      
//請(qǐng)求頭

      xhRequest.setRequestHeader(
"Content-Type","application/x-www-form-urlencoded");

      xhRequest.send(data);

};

在請(qǐng)求的回調(diào)函數(shù)中,目前只是先簡(jiǎn)單的打印了相應(yīng)的文本內(nèi)容,實(shí)際上應(yīng)該在這里做更多的事,詳情咱們下節(jié)再聊。如果你看到類似下面這樣的輸出內(nèi)容,說(shuō)明登錄的請(qǐng)求成功了。如果沒(méi)有成功,很可能是因?yàn)槲乙呀?jīng)換掉了用戶名和密碼,用你自己的Google帳戶試試看。

應(yīng)該看到的內(nèi)容:

SID

DQAAAHYAAADYQ4hToTAEYRu0uEXP9yXZ1uc_W3-kBtZFpug78XQDGiykOb-Sv2qdXtdUOL-
npRJm9SSq-AEvSBodrcuy3UwgFM8SX_z6fXzpGaJzHzQx5YTzR0AJHCEkFh
4yOoBFs0iCE2LI0LWQs6_2BFyIuLLMwRA8m3vfuVzNE3CHjrUHZA

LSID

DQAAAHgAAAClSiMWRfKAonW8zIytZ7NEizJNMQZojiNqsDxm3elei36MV
7GzM72bMiqdQawt8Fd1Dpp68p5bs1XYOXUPmDunUsZM1BZsAiXbIEouAJz1XjlysUQG-0p9969zYCvUm2tqWkA1BFVU2UqvjMAaBSgj10VkZzvcAbZB8nQf_mwRyg

Auth

DQAAAHcAAAClSiMWRfKAonW8zIytZ7NEizJNMQZojiNqsDxm3elei36
MV7GzM72bMiqdQawt8FcmxySIt75kfLxcis5BZnNCsyVuCwKM-DtNZcToUtm9IWoJyvNbUD9UTFYZPdBu1OyXsfY_QJHZfZdAT2QC
cExSIYKMvLfhhit9RPz4Gk2xlQ/n

Auth那一項(xiàng)后面的值就是token啦,可以不被砍頭了。

附錄:已知的Google服務(wù)及服務(wù)名

Calendar Data API

cl

Google Base Data API

gbase

Blogger Data API

blogger

Contacts Data API

cp

Documents List Data API

writely

Picasa Web Albums Data API

lh2

Google Apps Provisioning API

apps

Spreadsheets Data API

wise

YouTube Data API

youtube



Jasper 2009-02-06 15:51 發(fā)表評(píng)論
]]>
Google Gadget 開(kāi)發(fā)入門(二)啰嗦的Gadget例子http://m.tkk7.com/zhenandaci/archive/2009/02/06/253494.htmlJasperJasperFri, 06 Feb 2009 02:08:00 GMThttp://m.tkk7.com/zhenandaci/archive/2009/02/06/253494.htmlhttp://m.tkk7.com/zhenandaci/comments/253494.htmlhttp://m.tkk7.com/zhenandaci/archive/2009/02/06/253494.html#Feedback0http://m.tkk7.com/zhenandaci/comments/commentRss/253494.htmlhttp://m.tkk7.com/zhenandaci/services/trackbacks/253494.html前文說(shuō)道開(kāi)發(fā)一個(gè)Gadget可以分為兩個(gè)步驟:先寫界面的XML文件,再寫邏輯部分的JavaScript。我們就遵循這個(gè)步驟來(lái)寫一個(gè)再簡(jiǎn)單也不過(guò)的Gadget。

用到的工具有兩個(gè),一個(gè)是隨Google Desktop SDK附帶的Gadget Designer,用來(lái)編寫并有限的預(yù)覽界面,還可以調(diào)試JavaScript(這個(gè)就更有限了);一個(gè)是Google Desktop,用來(lái)測(cè)試寫好的Gadget。下面要寫的例子是我在為某研究院某個(gè)項(xiàng)目策劃階段作POC時(shí)所寫的一個(gè)小例子,可以顯示一個(gè)Google用戶的Picasa相冊(cè)中的Album名稱和縮略圖。雖然很小,但包含了Google賬戶的自動(dòng)登錄,顯示網(wǎng)絡(luò)圖片,XmlHttpRequest的使用等很多實(shí)用技巧。整個(gè)完成之后是這個(gè)樣子:

 

請(qǐng)跟我一起來(lái)。現(xiàn)在打開(kāi)Gadget Designer,選擇File->New Gadget,輸入了名稱“Picasa”之后,就可以看到一個(gè)完整Gadget的雛形了。你可以找到這個(gè)項(xiàng)目所在的文件夾,雙擊其中的gadget.gmanifest,此時(shí)如果你已經(jīng)安裝了Google Desktop,就可以看到Desktop自動(dòng)啟動(dòng),并把這個(gè)很“白”的Gadget(別笑,除了一張白色背景圖片以外,確實(shí)什么也沒(méi)有)顯示在Sidebar中。如圖:

clip_image002

到項(xiàng)目文件夾里可以看到一個(gè)main.xml文件和一個(gè)main.js文件。我們的界面就是在main.xml文件里指定的,打開(kāi)它,可以看見(jiàn)它指定了一張GadgetDesigner幫我們生成的白色png圖片作背景,還指定了我們要導(dǎo)入哪些個(gè).js文件。我們來(lái)小改兩個(gè)地方:



<view height="150" width="250" onopen="view_onOpen()">

<img src="stock_images\background.png" />

<script src="main.js" />

</view>

一是把view的height改成250,二是給img元素添加一個(gè)屬性name并給一個(gè)值,就像這樣:

<img name=”bgImage” src="stock_images\background.png" />

 

然后雙擊gadget.gmanifest,看看更改效果:

clip_image003

乍一看貌似沒(méi)什么改變,但是注意看我用黑色線圈出來(lái)的那一條橫杠,那是我們的Gadget的下邊沿,說(shuō)明它的高度還是變化了,但是白色的背景沒(méi)有變,因?yàn)槲覀儧](méi)有改變背景圖片的大小。現(xiàn)在通過(guò).js文件中代碼的方式來(lái)改變背景圖片的高度,可以看出些有意思的東西。

打開(kāi)main.js文件,你應(yīng)該會(huì)看到一個(gè)view_onOpen()函數(shù),這就是Gadget啟動(dòng)時(shí)會(huì)自動(dòng)調(diào)用的第一個(gè)函數(shù)(好吧,并不嚴(yán)格,但是在調(diào)用的順序上,它的確是相當(dāng)靠前的),我們就在這個(gè)函數(shù)內(nèi)部添加下面這一句:

bgImage.height=250;

再雙擊gadget.gmanifest運(yùn)行看看,白色背景也變高了吧。

我知道你一定會(huì)問(wèn),代碼里的bgImage是什么東西?怎么沒(méi)見(jiàn)在任何地方聲明這個(gè)變量,也沒(méi)見(jiàn)任何地方作初始化呢?回想我們剛才在main.xml文件里做了什么?我們給背景圖片取了一個(gè)名字,叫bgImage,而且別懷疑,你在代碼里訪問(wèn)的這個(gè)bgImage,正是那張圖片!背后的工作就是Gadget Host通過(guò)JavaScript引擎為我們做的,凡是在.xml文件里放置的東西(無(wú)論什么,圖片也好,按鈕也好,一個(gè)抽象的div也好),只要你給了一個(gè)name屬性,在JavaScript代碼中就可以直接使用這個(gè)名字來(lái)訪問(wèn)該對(duì)象(前提是你給的名字得是獨(dú)一無(wú)二的),這與瀏覽器中隨時(shí)可以訪問(wèn)document對(duì)象而不用做任何聲明一樣,那是瀏覽器這個(gè)運(yùn)行環(huán)境提供的對(duì)象,隨時(shí)可用。

另一個(gè)值得注意的地方是在.xml文件里,屬性的值都必須加上引號(hào),像height=”250”(因?yàn)槟抢锸褂玫氖菢?biāo)準(zhǔn)的xml語(yǔ)法),而在JavaScript代碼中,就要根據(jù)屬性具體的類型來(lái)決定,像高度這種整數(shù)型的值,就不用加。

你可能還會(huì)問(wèn),那么bgImage這個(gè)對(duì)象,是什么類型的,它有些什么屬性和方法可供我使用呢?它是一個(gè)img類型的對(duì)象,參考http://code.google.com/intl/zh-CN/apis/desktop/docs/gadget_apiref.html這個(gè)鏈接,這也是Google Desktop Gadget的API參考頁(yè)面,列出了Gadget Host提供的各種對(duì)象屬性和方法的說(shuō)明(雖然事實(shí)驗(yàn)證,Google自己列的這些都不全面,后話)。

最后叮囑一句:盡管main.xml文件里的東西(什么img啊,以后還會(huì)加進(jìn)div啊,checkbox之類的東西)看起來(lái)多么的像HTML,Gadget都和Web沒(méi)有天然的聯(lián)系。Google自己發(fā)布了一些Gadget,例如Gmail和Google Docs,外觀與這兩個(gè)服務(wù)的網(wǎng)頁(yè)非常像,再加上Gadget也主要使用JavaScript開(kāi)發(fā)(也少不了Universal Gadget跟著摻合),間接導(dǎo)致了總有人把Gadget顯示的地方考慮成一個(gè)小的瀏覽器窗口,而想把Web的一些東西簡(jiǎn)單的放在這里,到底行不行呢?李寧說(shuō):一切皆有可能。阿迪說(shuō):沒(méi)有不可能。匹克說(shuō):我能,無(wú)限可能。我要說(shuō):可能,但很難(笑)。

所以在編寫Gadget的時(shí)候,最好的方法是把它當(dāng)成純粹的桌面程序,忘掉Web的那一套。

這一節(jié)給大家入個(gè)門,下一節(jié)開(kāi)始說(shuō)說(shuō)在Gadget中怎么做Google帳戶的登錄,還會(huì)很羅嗦的,請(qǐng)見(jiàn)諒(笑)。




Jasper 2009-02-06 10:08 發(fā)表評(píng)論
]]>
Google Gadget 開(kāi)發(fā)入門(一)Gadget的組成&mdash;&mdash;兩個(gè)視角http://m.tkk7.com/zhenandaci/archive/2009/02/05/253460.htmlJasperJasperThu, 05 Feb 2009 14:23:00 GMThttp://m.tkk7.com/zhenandaci/archive/2009/02/05/253460.htmlhttp://m.tkk7.com/zhenandaci/comments/253460.htmlhttp://m.tkk7.com/zhenandaci/archive/2009/02/05/253460.html#Feedback0http://m.tkk7.com/zhenandaci/comments/commentRss/253460.htmlhttp://m.tkk7.com/zhenandaci/services/trackbacks/253460.html在Gadget開(kāi)發(fā)人員看來(lái)——我當(dāng)然是指你我這樣的IT民工,來(lái)開(kāi)發(fā)一個(gè)Gadget的人,而不是Google大樓里成天琢磨怎么和微軟對(duì)著干的那幫子人——一個(gè)Gadget由三大部分組成:描述UI的一系列.xml文件;存放程序邏輯的.js文件以及資源。

下面是一個(gè)Gadget項(xiàng)目在Google Desktop Disigner里面的結(jié)構(gòu)截圖。

clip_image001

資源這東西好理解,無(wú)非是程序要用到的各種圖片啦,字符串啦等等。讀者:字符串?什么意思?答:把程序會(huì)用到的一系列字符串統(tǒng)一存放,想引用的時(shí)候使用一個(gè)常量名字就可以,而不必在需要這些字符串的地方每次都重寫一遍,和Java中的property文件作用類似。

其余的兩部分會(huì)分節(jié)來(lái)詳細(xì)講解。

當(dāng)然說(shuō)只有三部分,是指我們大多只關(guān)心這么多,實(shí)際上還有第四部分,一個(gè)Gadget Settings文件,其中大多是關(guān)于這個(gè)Gadget的元信息,什么作者啊,創(chuàng)建日期啊,uuid啊,戶口所在地啊,最高學(xué)歷啊,婚姻狀況啊,哦,我給說(shuō)成簡(jiǎn)歷了(笑)。

前面也說(shuō)到過(guò),一個(gè)Gadget其實(shí)就是一個(gè)桌面應(yīng)用程序(再一次的,不管寫起來(lái)某些語(yǔ)法多么得像HTML,Gadget與Web都沒(méi)有天然的聯(lián)系),只不過(guò)這個(gè)程序在Gadget Host的管理之下,行話叫“托管”。Windows下沒(méi)有單獨(dú)的Gadget Host,它被合并在Google Desktop里面(算是另一種捆綁吧)。而Linux下的確有干干凈凈的Gadget Host,且有源碼下載,我們所有對(duì)Gadget的理解也都源于這個(gè)版本和相關(guān)的文檔。

那么在Gadget Host看來(lái),一個(gè)Gadget是什么東西呢?

以我寫的一個(gè)小Picasa Gadget為例,在Picasa Gadget初次加載之前,它是一個(gè).gg的壓縮包(其實(shí)就是一個(gè)標(biāo)準(zhǔn)的zip包,被改了后綴名而已),Gadget Host會(huì)從中讀取需要的文件,然后做相應(yīng)的解釋。

Gadget Host可以看成只有兩部分組成:一個(gè)UI的渲染器和一個(gè)JavaScript引擎。

說(shuō)UI渲染器之前就不得不回頭重提剛才說(shuō)到的一個(gè)Gadget包括了一系列.xml文件這件事。實(shí)際上這些.xml文件就是用來(lái)指定你想寫的Gadget的界面的,就是說(shuō),你的Gadget跑起來(lái)以后長(zhǎng)成什么樣子,是由這些個(gè).xml文件來(lái)決定的(當(dāng)然,嚴(yán)格說(shuō)來(lái)可以使用JavaScript在運(yùn)行時(shí)改變一些內(nèi)容,但請(qǐng)不要抬杠,笑)。

這些.xml文件中最主要的是main.xml這個(gè)文件,你的Gadget窗口有多大,在什么位置有幾個(gè)按鈕,列表有沒(méi)有滾動(dòng)條,背景是什么顏色等等,都在這里指定。還包括這些東西上的事件監(jiān)聽(tīng)函數(shù)也一并在這里聲明(不知為何,讓我莫名的想起微軟的MFC,當(dāng)然,嚴(yán)格說(shuō)來(lái)可以使用JavaScript在運(yùn)行時(shí)動(dòng)態(tài)改變這些內(nèi)容,但請(qǐng)不要再次抬杠,笑)。

UI渲染器干什么呢?就是來(lái)把這個(gè).xml所要求的界面轉(zhuǎn)換成具體的系統(tǒng)調(diào)用,讓操作系統(tǒng)來(lái)完成繪圖(好吧好吧,你喜歡嚴(yán)格,那我告訴你,Linux版本下首先被轉(zhuǎn)換為Qt的C++類,由Qt來(lái)發(fā)起對(duì)系統(tǒng)繪圖的調(diào)用)。

既然Gadget的程序邏輯都使用JavaScript來(lái)編寫,理所應(yīng)當(dāng)?shù)模珿adget Host必然要包含一個(gè)JavaScript解釋器來(lái)解釋這些代碼,這個(gè)解釋器也被叫做JavaScript引擎。Gadget Host里確實(shí)有這么個(gè)東西,叫做Spider Monkey,它恰好也是FireFox所使用的JavaScript引擎。廣義上說(shuō),一個(gè)引擎的作用主要是解釋它遇到的一切JavaScript代碼,如果代碼使用到核心JavaScript的功能和對(duì)象,它便直接提供;如果代碼使用到了一些依賴于底層的對(duì)象(例如Gadget Host就提供了很多專有的JavaScript對(duì)象和方法供使用,這些都是核心JavaScript之外的東西),則引擎還要負(fù)責(zé)轉(zhuǎn)發(fā)這樣的請(qǐng)求(你可以說(shuō),這實(shí)際上是適配器做的事,我這樣簡(jiǎn)化有助于理解,請(qǐng)不要一再抬杠,笑)。

也可以這樣從邏輯上看Gadget的組成:即一個(gè)Gadget就是一組圖形界面,加這些界面上每個(gè)控件(按鈕啊,列表啊,輸入框等等)的事件監(jiān)聽(tīng)函數(shù),這種界面描述與事件邏輯分離的程序模型,和微軟的XAML+C#簡(jiǎn)直如出一轍。因此一個(gè)Gadget的開(kāi)發(fā)實(shí)際上也就可以分為這兩大步驟:先寫界面的XML文件,再寫邏輯部分的JavaScript。下面一節(jié)就用一個(gè)小例子來(lái)看看具體如何做。別嫌我說(shuō)得太詳細(xì)哦。



Jasper 2009-02-05 22:23 發(fā)表評(píng)論
]]>
主站蜘蛛池模板: 亚洲精品天堂在线观看| 久久久久亚洲AV无码网站| 亚洲综合激情五月丁香六月| 国产人成免费视频网站| 337p日本欧洲亚洲大胆艺术| 美女视频黄的免费视频网页| 国产aⅴ无码专区亚洲av| 在线观看免费视频一区| 久久国产亚洲观看| 99re这里有免费视频精品 | 成人黄软件网18免费下载成人黄18免费视频 | 国产精品免费视频播放器| 亚洲成AV人片在WWW| 国产成人免费a在线视频色戒| 老司机亚洲精品影院在线观看| 一本色道久久88综合亚洲精品高清| 鲁啊鲁在线视频免费播放| 亚洲一区二区精品视频| 精品多毛少妇人妻AV免费久久| 国产亚洲一区二区在线观看| 99精品视频在线观看免费专区 | 亚洲精品国产成人99久久| 真实国产乱子伦精品免费| 亚洲 日韩 色 图网站| 午夜亚洲国产成人不卡在线| 精品四虎免费观看国产高清午夜| 亚洲综合网美国十次| 午夜一级免费视频| 久久国产精品免费| 亚洲另类春色国产精品| 日韩精品电影一区亚洲| 久久久精品午夜免费不卡| va天堂va亚洲va影视中文字幕| 免费国产高清视频| 无码国产精品一区二区免费式芒果 | 亚洲精品亚洲人成在线观看| 1000部夫妻午夜免费| 亚洲AV无码成人网站在线观看| 亚洲老妈激情一区二区三区| 大地资源二在线观看免费高清| 一区二区三区免费视频播放器|