[Windows Mobile .NET CF] 拍照上傳 Flickr – Day2

[Windows Mobile .NET CF] 拍照上傳 Flickr – Day2

拍拍拍~~
如果寫隻程式只能拍照, 也未免太沒用了.
現在 Windows Mobile 內建的拍照程式只能上傳到 Windows Live Space…
如果想要直接上傳到 Flickr 或其他空間, 就不是很方便…
嗯…趕快進入主題吧.

首先, Flickr 是有 API 的, 也有人寫好了 .NET 的 Flickr API , 也支援 .NET CF.
所以我們直接用這個 Flickr .NET API Library 就方便多了. (要下載原始碼回來自己編譯成為 .NET CF 的版本歐!)
而 Flickr API 需要申請 API Key ,
申請的網址在 http://www.flickr.com/services/api/keys
以下在原始碼當中我就將我自己的 Key 換成 123456789 , 請不要照用該 key,
而是要自己申請才是, 因為 Flickr 不允許洩漏 key 的.
對於 Flickr API 想要有更多了解的話, 可以參考 http://blogs.msdn.com/coding4fun/archive/2006/11/22/1126978.aspx

好了, 可以開始寫 code , 現在開始改良 CameraNow 這隻程式,
在 Form1 的下方, 應該可以看到 MainMenu1 , 這個就是一般 Windows Mobile 的下方快速 menu,
利用這個可以很快讓使用者選擇一些功能, 而不用花時間設計 UI.

image

基於微軟工程師的思維, 沒有左邊的 menu 選項就生不出右邊的 menu 選項…
所以我左邊放個結束, 右邊放個功能, 在功能內加了兩個, 上傳跟設定.
設定內放一個認證的功能.

image

因為 Flickr 上傳照片的做法, 是需要取得帳號的認證碼, 依照這個認證碼的權限,
你的程式就可以上傳或刪除照片, 或只能下載照片等等.
而使用者端也可以隨時改變認證碼的權限或刪除.
基本上程式不應該直接取得使用者的帳號密碼, 因為這樣使用者就暴露了帳號密碼給該程式了,
誰知道那個程式會搞啥鬼呢???
所以當我下載了 zipphoto 它要我輸入 Flickr 的帳號密碼給它…這真的很不合邏輯呢.

那, 先寫結束吧…
在一般的 Windows 程式當中, 我們是不需要寫結束這個功能的.
但是微軟工程師的邏輯是, Windows Mobile 的程式一旦啟動, 最好一直在記憶體當中等候使用者…
所以 Windows Mobile 的程式沒有內建關閉程式的功能.
都要讓使用者越過千山萬水點到設定內的記憶體管理的結束程式….
嗯, 要寫結束是很簡單的, 程式碼如下:


{
    Close();
}

那麼…取得 Flickr 認證的方法呢…
有點複雜, 簡單來說, 就是程式要啟動一個 url 讓使用者連到 Flickr 做授權的動作.
之後, 程式可以透過 API 取得授權碼.
然後以後就不需要再次授權, 每次只要透過授權碼就可以做上傳照片的動作了.

為了儲存這個授權碼, 所以我寫了一個 class 來儲存.
也示範了 .NET CF 做 Xml Serialization 的方法, 很簡單的.


using System.Xml.Serialization;

namespace CameraNow
{   
    public class Settings
    {
        public string FlickrAuthToken { get; set; }

        public static Settings Load(string filename)
        {
            if (File.Exists(filename) == false)
                return new Settings();

            XmlSerializer ser = new XmlSerializer(typeof(Settings));
            using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
            {
                return ser.Deserialize(fs) as Settings;
            }
        }

        public void Save(string filename)
        {
            XmlSerializer ser = new XmlSerializer(typeof(Settings));
            using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
            {
                ser.Serialize(fs, this);
            }
        }
    }
}

那麼整個啟動授權, 一直到把授權碼存起來的程式碼如下:


{
    string tempFrob = flickr.AuthGetFrob();
    string flickrUrl = flickr.AuthCalcUrl(tempFrob, AuthLevel.Write);

    // 呼叫 browser 在 web 端取得授權.
    System.Diagnostics.Process.Start(flickrUrl, string.Empty);

    MessageBox.Show("請在 Browser 取得認證後關閉這個視窗");

    try
    {
        Auth auth = flickr.AuthGetToken(tempFrob);
        settings.FlickrAuthToken = auth.Token;
        settings.Save(settingfile);
        flickr.AuthToken = auth.Token;
    }
    catch (FlickrException ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

看起來還算簡單吧?!

上傳照片的程式就更簡單了, 幾乎是一行就解決了,
其他的程式碼都只是為了保險或是通知使用者而已.


{
    if (string.IsNullOrEmpty(flickr.AuthToken) == true)
    {
        MessageBox.Show("尚未取得授權");
        return;
    }

    flickr.UploadPicture(imagefilename, "CameraNow", "Photo by CameraNow at " + DateTime.Now.ToString());

    MessageBox.Show("上傳成功");
}

當然, 初始化的動作也是不可以少的,


private string settingfile;
private Settings settings;
private string imagefilename;

public Form1()
{
    InitializeComponent();

    flickr = new Flickr("123456789 — Flickr API Key", "123456789 – Flickr API Shared password");

    settingfile = Path.Combine(
        Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName),
        "settings.xml");
    settings = Settings.Load(settingfile);
    if (string.IsNullOrEmpty(settings.FlickrAuthToken) == false)
        flickr.AuthToken = settings.FlickrAuthToken;
}

唯一要注意的就是上面的 flickr API Key 跟 Shared Password 是要去 Flickr 申請才有的.

這樣就完成了拍照上傳的程式囉,

原始碼可以在這裡下載

不過, 因為這個原始碼的 API Key 是假的,
如果你只是想玩看看程式, 不想自己編譯,
可以下載已經編譯好, 可以執行的程式檔案 (裡面的 API Key 是真的)