使用Yahoo API 抓取即時匯率

最近老大派下拿來練手的是一個匯率換算的APP,今天總算告一個段落了~稍微紀錄一下免得之後又忘記了

要求

  1. 使用Yahoo API
  2. 透過HttpURLConnection class 將資料以Json型態取下並顯示在手機上



這篇網誌已經過時了!
Yahoo! 財務API服務,該服務已停止並且不再起作用。
我已經換新的API實作了,改天有空再來寫一篇新的。



事前的了解

  1. Yahoo API提供的 URL
    連接下面的URL會得一份CSV檔案,文件內容會是新台幣兌美金的匯率
    http://download.finance.yahoo.com/d/quotes.csv?e=.csv&f=c4l1&s=TWDUSD=x

    • 其中URL裡的f=c4l1是只取下兌換幣別(美金)的代碼與匯率
      如果想取下更詳細的資料可以換成f=sl1d1t1,分別指定了代碼(含原始幣別跟對換幣別)、匯率、日期、時間這四個欄位

    • s=TWDUSD=x ,其中TWD (新台幣) 為原始幣別 USD (美金)為兌換幣別,可以依需求自行更換,如果要查詢多筆資料則在後在後接續即可。
      http://download.finance.yahoo.com/d/quotes.csv?e=.csv&f=c4l1&s=TWDUSD=x,TWDJPY=x

  2. 轉成JSON檔
    接下來要將CSV檔轉成JSON,只要透過Yahoo csv parser將第一步的URL轉換成YQL(Yahoo Query Language)格式的URL即可。

    在YOUR YQL STATEMENT的框中將SQL修改為 select * from csv where url=‘上面獲得csv檔的url’ ,按下test按鈕,即可得到對應JSON檔的新URL

  3. 取得全部幣別
    因為我希望使用下拉式的方式讓使用者選擇原始幣別與兌換幣別,避免輸入錯誤的可能,所以我必須先取得一份全部幣
    http://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json

    透過這個URL就可以取得所有幣別JSON檔,只是上面只有代碼,沒有貨幣全稱,不過還好規範命名規則是走ISO 4217,還是有辦法知道,麻煩了點就是。



實作GO~!!

  1. 在要讀取匯率資料的地方貼上

    String urlConnect = "對應JSON檔的新URL";
    URL url = new URL(urlConnect);
    HttpURLConnection conn = (HttpURLConnection)url.openConnection();
    InputStreamReader isr = new InputStreamReader(conn.getInputStream());
    BufferedReader in = new BufferedReader(isr);
    String line = in.readLine();
    

    如此就可以讀到JSON檔的內容

  2. 解析JSON檔內容
    讀到資料就像下面這麼一大串,不過這樣其實很不好看,所以我會用JSON的排版器排一下好看一下該怎麼拆

    {"query":{"count":2,"created":"2016-03-15T03:00:22Z","lang":"zh-TW","diagnostics":{"publiclyCallable":"true","url":{"execution-start-time":"1","execution-stop-time":"629","execution-time":"628","content":"http://download.finance.yahoo.com/d/quotes.csv?e=.csv&f=c4l1&s=TWDUSD=x,TWDJPY=x"},"user-time":"629","service-time":"628","build-version":"0.2.420"},"results":{"row":[{"col0":"USD","col1":"0.0305"},{"col0":"JPY","col1":"3.4708"}]}}}
    

    基本上在JSON中大括號 { }指物件(object)、中括號 [ ] 指陣列(array)、引號""則是指元素

    所以像上面這一串所要取出的順序是這一串物件中→ query物件→results物件 → row陣列,最後在取出每個index中所包含的物件,而物件中的元素col0、col1分別對應到兌換幣別(美金)的代碼與匯率

    如此就取出了所需的兌換幣別(美金)的代碼與匯率



踩雷

基本上做到上面就完成大慨了,只是實際執行的時候,會跳出下面兩個error

  1. android.os.NetworkOnMainThreadException
    查了一下,這個是因為我把網路的活動跑在main Thread上,貼心過頭Google大神告訴你,你的APP可能會因為等待網路活動的回應太久,而被系統強制關閉。

    解決的方式只要開新的執行緒就好,不管是用Thread、Handle、AsynTask都行把它掉離main Thread就行

  2. android.system.ErrnoException: android_getaddrinfo failed: EACCES (Permission denied)
    另一個會收到的是這個,主要是告訴你uses-permission忘了開,只要去AndroidManifest.xml中添加即可



參考資料

留言

這個網誌中的熱門文章

Genymotion 模擬器安裝篇:In ubuntu14.04 LET