[C#][Windows Phone]利用WebCLient去完成Google Reader標記閱讀(Mark as read)

上一篇文章有講解利用HttpWebRequest的方式來完成Google Reader中的標記閱讀,但是因為edit-tag本身就不屬於太消耗時間的動作。與其去用HttpWebRequest的非同步的方式,不如使用容易又好用的WebClient,所以我就把我原來程式碼做了一點修改。

 public void MarkArticleAsRead()
        {
            CurrentTransType = Transaction_Type.MARK_AS_READ;
            string auth_params = string.Format("https://www.google.com/reader/api/0/edit-tag?client=scroll&format=joson&ck=" + DateTime.Now.Ticks.ToString());

            string postData = "";
            postData += "&i=tag:google.com,2005:reader/item/fa42c976c848ecf4";
            postData += "&a=user/-/state/com.google/read";
            postData += "&s=feed/http://funiphone.pixnet.net/blog/feed/rss";
            // Note the token must get within 30 mins
            postData += "&T=//mUESPUMtDyZh6BaFXd-CqQ";


            WebClient wc = new WebClient();
            wc.Headers["Content-type"] = "application/x-www-form-urlencoded";
            wc.Headers["Authorization"] = "GoogleLogin auth=" + UserAuth;
            wc.Headers["Cookie"] = "SID=" + UserSid;
            try
            {
                wc.UploadStringAsync(new Uri(auth_params), "POST", postData);
            }
            catch (WebException e)
            {
                //handle error if any
            }
        }
<font face="Georgia">幾個需要注意的地方如下:</font>
  • UserAuth與UserSid 需要先對Google API做login的部分
  • Content-type是必須要先填成這樣,我試過uff8會失敗~

[C#][Windows Phone]如何使用Google reader API標記已經閱讀 (mark as read)

雖然網路上沒有完整使用C#與Windows Phone 7.1的範例,不過還是盡量用中文來寫這篇吧。其實網路上英文的資料應該也不少,不論是pyrfeed這裡的Google API列表,還是Unofficial Google Reader API或是R2 google reader on Google code。不過要完整的C#還有Windows Phone 7.1的sample code我也是想辦法K了半天這三份API文件然後不斷的測試,在這裡就列出一些片段的程式碼。

public void MarkArticleAsRead(string newID)
{
            string auth_params = string.Format("https://www.google.com/reader/api/0/edit-tag?client=scroll&format=joson&ck=" + DateTime.Now.Ticks.ToString());

            HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(auth_params);
            httpRequest.Method = "POST";
            httpRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
            httpRequest.Headers["Authorization"] = "GoogleLogin auth=" + UserAuth;
            httpRequest.Headers["Cookie"] = "SID=" + UserSid;
            httpRequest.BeginGetRequestStream(new AsyncCallback(GetPostRequestStreamCallback), httpRequest);
        }    

不過這裡有一些需要注意的是SID與auth ID需要另外區擷取,這在我其他文章提到。不過接下來就是重點的部分。也就是post data該如何填、該放哪些資料。

 private static void GetPostRequestStreamCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

            // End the operation
            Stream postStream = request.EndGetRequestStream(asynchronousResult);
            string postData = "";
            postData += "&i=tag:google.com,2005:reader/item/fa42c976c848ecf4";
            postData += "&a=user/-/state/com.google/read";
            postData += "&s=feed/http://funiphone.pixnet.net/blog/feed/rss";
            // Note the token must get within 30 mins
            postData += "&T=//mUESPUMtDyZh6BaFXd-CqQ" + LoginToken;

            // Convert the string into a byte array.
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);

            // Write to the request stream.
            postStream.Write(byteArray, 0, postData.Length);
            postStream.Close();

            // Start the asynchronous operation to get the response
            request.BeginGetResponse(new AsyncCallback(GetPostResponseCallback), request);
        }

在這裡也要注意的是Token需要再30分鐘之內取得~ 建議是呼叫之前馬上去取得token來使用。還有這裡的參數”a=”user 之後有user id 需要填,在這裡就不列出來。 &i=要填的是news 的id,還有&s=要填的是rss ID,你可以在另外一個參數”http://www.google.com/reader/api/0/stream/contents/user” 去取得。最後是結果的部分:

private static void GetPostResponseCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

            // End the operation
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
            Stream streamResponse = response.GetResponseStream();
            StreamReader streamRead = new StreamReader(streamResponse);
            string responseString = streamRead.ReadToEnd();
            // "responseString" should be "OK" if post succucess

            // Close the stream object
            streamResponse.Close();
            streamRead.Close();
            response.Close();
        }

這裡重要的是~ 如果這篇文章被mark as read你就會得到OK,但是如果之前已經mark as read你就會得到一個exception,這是需要注意的。

目前先寫到這裡~ 找時間把全部的流程跑一次~ 順便講解一下JSON的部分。

[Windows Phone][C#]最近寫了一個Windows Phone的Google Reader APP

本篇文章應該會用中文撰寫到完,接續著我前幾篇的文章,我一共寫了幾篇跟Google Reader溝通有關的文章。也讓我來仔細敘述當初為何會有這些文章的出現吧。

大概是兩個月前XDite大大在plurk po了一篇 “我要在一個月之內把Reeder幹出來” (大概是這樣吧!雖然我忘記原文了,而且大大好像後來也刪除了)。其實那一篇我看了以後很震撼~ 對喔!! 可以利用完全仿製另外一個商用APP的方式來練功。

於是我也開始撰寫APP,由於我自己只有iPhone,但是卻沒有任何MAC的電腦可以給我提供開發的環境,也只好拿公司最容易找到工具。Microsoft的 Visual Studio來撰寫Windows Phone。

一路上從四月才開始把專案建起來到現在,從完全不會寫Windows Phone到搞定Data Binding、知道如何使用Lambda與Delegate、也慢慢把Windows Phone原件搞懂,當然好久沒摸的WPF也開始拿回來K了一陣,到最後的LINQ、JSON(這個方便應該之後會寫一篇文章來做個說明)。其實寫好一個Google Reader App能夠學習的APP技巧真的不少,在這裡也稍微列一下:

  • 為了登入Google API的服務, 一開始要學習的就是如何去處理網路溝通的方式,面對的就是 HttpWebRequest與WebClient。 當然這篇文章也幫助我很多。在這時候一併就把Lanbda與Delegate 的觀念學起來,畢竟你得要處理threading與UI呈現的問題。

  • 登入Google Reader API之後就沒事情了嗎? 還要好好的去處理溝通過來得資料,這裡你當然可以乖乖的使用XML的方式或是直接跳到JSON的方式。 還好之前學習的Linq與JSON就派上用場。不過Google Reader的JSON資料也怪怪的~ 為了去處理這些東西~也讓我對JSON的觀念更佳的清楚了。

  • 抓回來的Label列表與文章列表要如何處理呢?這時候又要跟WPF裡面的ListBox開始奮戰,這時候你又得跟Data Binding還有WPF XAML的語法來奮鬥。

  • 別忘了最後~ 由於你需要離線閱讀還以記錄使用者的登入資訊。這時候又要跟Local database on Windows Phobne來奮鬥。不過這個算簡單的,畢竟LinQ步算是太難入門的東西。

到目前為止利用自己上班剩餘時間,大概忙了三個禮拜的結果,目前已經可以登入與看文章。由於在今天好不容易把Google Reader裡面的設定閱讀(mark it as read)也搞定了。 現在也才可以寫篇文章做點記錄。不過接下來才是Reeder令人激賞的好用地方,我也先把自己的TODO 列一下:

  • 順暢與讀體驗與文章下載(裡面包含著完全不影響使用者閱讀的離線下載)

  • 將你喜歡的文章轉載到各個社群媒體Facebook,Evernote…. 等 (希望懂了JSON可以讓之後的路更順暢)

  • 使用者介面得更加美化 (這是我的盲點~~~~~)

好啦!! 今天也總算把基本功能都完成了! 繼續努力了~~~

本站也開始支援SyntaxHighlighter

SyntaxHighlighter是一個在網站上相當好用的東西。我終於也在www.evanlin.comblog把他安裝好了
</br>不過呢~ 由於Window Live Writer 還沒有找到真的讓我覺得很好用的部分
</br>這個Plugin 不好用(更正: 因為不支援最新版本的Syntaxhighlighter 3.0.8.3)
</br>以下是我加入到MT 模板的code(不過這是用VSpaste)先貼的

  <span style="color:green;"><!-- Include required JS files -->
    </span><span style="color:blue;"><</span><span style="color:#a31515;">script </span><span style="color:red;">type</span><span style="color:blue;">="text/javascript" </span><span style="color:red;">src</span><span style="color:blue;">="js/shCore.js"></</span><span style="color:#a31515;">script</span><span style="color:blue;">>
    <</span><span style="color:#a31515;">script </span><span style="color:red;">type</span><span style="color:blue;">="text/javascript" </span><span style="color:red;">src</span><span style="color:blue;">="js/shBrushJScript.js"></</span><span style="color:#a31515;">script</span><span style="color:blue;">>
    <</span><span style="color:#a31515;">script </span><span style="color:red;">type</span><span style="color:blue;">="text/javascript" </span><span style="color:red;">src</span><span style="color:blue;">="js/shBrushCSharp.js"></</span><span style="color:#a31515;">script</span><span style="color:blue;">>
    <</span><span style="color:#a31515;">script </span><span style="color:red;">type</span><span style="color:blue;">="text/javascript" </span><span style="color:red;">src</span><span style="color:blue;">="js/shBrushCss.js"></</span><span style="color:#a31515;">script</span><span style="color:blue;">>
    <</span><span style="color:#a31515;">script </span><span style="color:red;">type</span><span style="color:blue;">="text/javascript" </span><span style="color:red;">src</span><span style="color:blue;">="js/shBrushJava.js"></</span><span style="color:#a31515;">script</span><span style="color:blue;">>
    <</span><span style="color:#a31515;">script </span><span style="color:red;">type</span><span style="color:blue;">="text/javascript" </span><span style="color:red;">src</span><span style="color:blue;">="js/shBrushXml.js"></</span><span style="color:#a31515;">script</span><span style="color:blue;">>

    <</span><span style="color:#a31515;">link </span><span style="color:red;">href</span><span style="color:blue;">="css/shCore.css" </span><span style="color:red;">rel</span><span style="color:blue;">="stylesheet" </span><span style="color:red;">type</span><span style="color:blue;">="text/css" />
    <</span><span style="color:#a31515;">link </span><span style="color:red;">href</span><span style="color:blue;">="css/shThemeDefault.css" </span><span style="color:red;">rel</span><span style="color:blue;">="stylesheet" </span><span style="color:red;">type</span><span style="color:blue;">="text/css" />
    </span><span style="color:green;"><!-- Include required JS files -->

    </span><span style="color:blue;"><</span><span style="color:#a31515;">script </span><span style="color:red;">type</span><span style="color:blue;">="text/javascript">
        </span><span style="color:#a31515;">SyntaxHighlighter.all()
    </span><span style="color:blue;"></</span><span style="color:#a31515;">script</span><span style="color:blue;">>
</span>

話說~ VSpaste 這個plugin 也很好用~ 跨Blog又不用安裝~

不過可能支援語系會少一點

以下是使用這個Windows Live Writer Plugin(Windows Live Writer Source Code plugin for SyntaxHighlighter) , 而且也支援最新版本的syntaxhighlighter 3.0.8.3

  <!-- Include required JS files -->
    <script type="text/javascript" src="js/shCore.js"></script>
    <script type="text/javascript" src="js/shBrushJScript.js"></script>
    <script type="text/javascript" src="js/shBrushCSharp.js"></script>
    <script type="text/javascript" src="js/shBrushCss.js"></script>
    <script type="text/javascript" src="js/shBrushJava.js"></script>
    <script type="text/javascript" src="js/shBrushXml.js"></script>

    <link href="css/shCore.css" rel="stylesheet" type="text/css" />
    <link href="css/shThemeDefault.css" rel="stylesheet" type="text/css" />
    <!-- Include required JS files -->

    <script type="text/javascript">
        SyntaxHighlighter.all()
    </script>

How to using google reader API on Windows Phone 7.1

Google data is good API tool for C# or other language to connect with Google related service, however here is no official Google Reader API on document. and Google data don’t support for Windows phone (only for Windows mobile for now).

However it could be found on web for some of unofficial document for Google Reader API as follows:

But however to come out detail implement for Windows Phone, it quit need time to work detail. Allow me try to list some major problems of this.

  • Most important of using HttpWebRequest is the error repose
> > The remote server returned an error: NotFound > >

It is most common error code your will find during you try to login or get any feedback on Window Phone. It could be either you missing your GET parameter or you missing your headers.

Here is some sample code related Login Google Reader and get list from this login. Some more detail communication code about HttpWebRequest, please check http://msdn.microsoft.com/zh-tw/library/system.net.webrequest.begingetrequeststream(v=vs.80).aspx

Something need to note before enter detail code.(check red part)

  • Need to authentication to get Auth_ID and SID for all API access.

  • Don’t miss your “Headers” when you trying to get API.

  • Http method need follow as document.

    public void LoginGoogleReader() { string email = “YOUR_EMAIL”; string passwd = “YOUR_PASSWORD”; string auth_params = string.Format(“https://www.google.com/accounts/ClientLogin?accountType=HOSTED_OR_GOOGLE&Email=” + email + “&Passwd=” + passwd + “&service=reader&source=J-MyReader-1.0”); HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(auth_params);

    httpRequest.Method = "POST";
            RequestState myRequestState = new RequestState();
            myRequestState.request = httpRequest;
            IAsyncResult result =
                (IAsyncResult)httpRequest.BeginGetResponse(new AsyncCallback(AuthRespCallback), myRequestState);
        }
    
        public void GetGoogleReaderPreferenceList()
        {
            string auth_params = string.Format("https://www.google.com/reader/api/0/preference/list?<font color="#ff0000">client=scroll&ck=1293954081436</font>");
    
    HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(auth_params);
    </br> httpRequest.Method = "GET"; httpRequest.Headers["Authorization"] = "GoogleLogin auth=" + UserAuth; httpRequest.Headers["Cookie"] = "SID=" + UserSid;
            RequestState myRequestState = new RequestState();
            myRequestState.request = httpRequest;
    
            IAsyncResult result =
                (IAsyncResult)httpRequest.BeginGetResponse(new AsyncCallback(AuthRespCallback), myRequestState);
        }
    

About Metro app Suspend/Resume and system sleep/Hibernate

According to Metro Application Lifetime sample and related document, it description about Metro app about suspend/resume.

However, I also find I could not make my Metro app enter suspend mode, so I try to figure out some answer from MSFT forum. Refer here and here.

Here is my summary for this:

  1. When leave app about 5 sec or trigger another app about 5 sec, the “suspend” event will called.

  2. “Suspends”/”Resume” event will trigger automatically when you not attach debugger on release build. See “Star without Debugging” on “debug” tab.

  3. If you using debugger, you only trigger “suspend” manually.

  4. Sleep/Hibernate will trigger “Suspend” if your app is release version without debugger attach.