利用Accuweather實作天氣APP

雖說這只是公司要求新人自己練習用的,但是自己從來沒寫過app(除非要說hello world也算的話),因此想自己嘗試看看做一個簡單的天氣app。

先註冊帳號之後取得專案apikey(沒有這個就不能從這個網站取資料啦)
之後會在程式裡面用到。

取當下天氣資料的字串大概是長這樣子的(抓的是日文資料,要改的話在網址後面的language=ja可以修改):
location_code和是地區碼(在這裡可以抓該網站專用的地區碼)

http://dataservice.accuweather.com/currentconditions/v1/"+location_code+"?apikey=" + apikey +"&language=ja";

大致上的概念就是,用這個網頁過去會直接收到一個json檔案,
然後把這個json檔案拆成很多部分放進app裡面。
按下手機上面的按鈕之後就會換頁,新的頁面會顯示天氣的資訊。


activity_main.xml (主頁面)
<linearlayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">

    <linearlayout android:layout_height="93dp" android:layout_width="match_parent" android:orientation="horizontal">
        <button android:id="@+id/button_sapporo" android:layout_height="wrap_content" android:layout_width="wrap_content" android:onclick="buttonOnClick" android:text="@string/sapporoText">
        </button><button android:id="@+id/button_yokohama" android:layout_height="wrap_content" android:layout_width="wrap_content" android:onclick="buttonOnClick" android:text="@string/yokohamaText">

        </button><button android:id="@+id/button_taipei" android:layout_height="wrap_content" android:layout_width="wrap_content" android:onclick="buttonOnClick" android:text="@string/taipeiText">
        </button><button android:id="@+id/button_vietnam" android:layout_height="wrap_content" android:layout_width="wrap_content" android:onclick="buttonOnClick" android:text="@string/vietnamText">
    </button></linearlayout>
    <linearlayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="horizontal">
        <button android:id="@+id/button_api" android:layout_height="wrap_content" android:layout_width="wrap_content" android:onclick="buttonOnClick" android:text="@string/button_api">

    </button></linearlayout>

</linearlayout>


weather.xml (用來顯示天氣結果)
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="93dp"
        android:orientation="horizontal">
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/sapporoText"
            android:id="@+id/button_sapporo"
            android:onClick="buttonOnClick"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/yokohamaText"
            android:id="@+id/button_yokohama"
            android:onClick="buttonOnClick"/>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/taipeiText"
            android:id="@+id/button_taipei"
            android:onClick="buttonOnClick"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/vietnamText"
            android:id="@+id/button_vietnam"
            android:onClick="buttonOnClick"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/button_api"
            android:id="@+id/button_api"
            android:onClick="buttonOnClick"/>

    </LinearLayout>

</LinearLayout>


MainActivity.java
import android.app.Activity;
import android.icu.text.SimpleDateFormat;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.text.ParseException;
import java.util.Date;

public class MainActivity extends Activity{
    String place = "";
    String apikey1 = "專案APIKEY1";
    String apikey2 = "專案APIKEY2";
    String apikey=apikey1;
    String location_code_taipei = "4-315078_1_AL";
    String location_code_vietnam = "1-353981_1_AL";
    String location_code_yokohama = "2383413";
    String location_code_sapporo = "1-223985_1_AL";

    String location_code="";
    String ENDPOINT= "";
    int flag=0;
    private RequestQueue requestQueue;
    @Override
    protected void onCreate(Bundle bundle){
        super.onCreate(bundle);
        setContentView(R.layout.activity_main);
        requestQueue = Volley.newRequestQueue(this);

    }

    private void fetchPosts(int i) {
        if (i==1){
            ENDPOINT= "http://dataservice.accuweather.com/currentconditions/v1/"+location_code+"?apikey=" + apikey +"&language=ja";
        }else if (i==2){
            ENDPOINT = "http://dataservice.accuweather.com/forecasts/v1/daily/1day/" + location_code + "?apikey=" + apikey + "&language=ja&metric=true";
        }
        StringRequest request = new StringRequest(Request.Method.GET, ENDPOINT, onPostsLoaded, onPostsError);
        requestQueue.add(request);
    }



    private final Response.Listener onPostsLoaded = new Response.Listener(){
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public void onResponse(String response){
            Log.i("PostActivity",response);
                try {
                    JSONArray jArr = new JSONArray(response);
                    JSONObject jo = jArr.getJSONObject(0);
                    System.out.println("LocalObservationDateTime:" + jo.getString("LocalObservationDateTime"));
                    TextView tmp = findViewById(R.id.time);
                    SimpleDateFormat timetmp = new SimpleDateFormat(jo.getString("LocalObservationDateTime"));
                    String inputPattern = "yyyy-MM-dd'T'hh:mm:ssX";
                    SimpleDateFormat inputFormat = new SimpleDateFormat(inputPattern);
                    Date date = null;
                    try {
                        date = inputFormat.parse(jo.getString("LocalObservationDateTime"));
                        tmp.setText(date.toString());
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    System.out.println("WeatherText:" + jo.getString("WeatherText"));
                    tmp = findViewById(R.id.weather);
                    tmp.setText(jo.getString("WeatherText"));
                    JSONObject Temperature = jo.getJSONObject("Temperature");
                    JSONObject Metric = Temperature.getJSONObject("Metric");
                    System.out.println("Temperature:" + Metric.getString("Value"));
                    tmp = findViewById(R.id.temperature);
                    tmp.setText(Metric.getString("Value"));
                    tmp = findViewById(R.id.place);
                    tmp.setText(place);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                try {
                    JSONObject jo = new JSONObject(response);
                    JSONObject Headline = jo.getJSONObject("Headline");
                    System.out.println("Text:" + Headline.getString("Text"));
                    JSONArray DailyForecasts = jo.getJSONArray("DailyForecasts");
                    JSONObject jo2 = DailyForecasts.getJSONObject(0);
                    JSONObject Temperature = jo2.getJSONObject("Temperature");
                    JSONObject Minimum = Temperature.getJSONObject("Minimum");
                    JSONObject Maximum = Temperature.getJSONObject("Maximum");
                    System.out.println("Minimum:" + Minimum.getString("Value"));
                    System.out.println("Maximum:" + Maximum.getString("Value"));
                    TextView tmp;
                    tmp = findViewById(R.id.forcastText);
                    tmp.setText(Headline.getString("Text"));
                    tmp = findViewById(R.id.min);
                    tmp.setText(Minimum.getString("Value"));
                    tmp = findViewById(R.id.max);
                    tmp.setText(Maximum.getString("Value"));
                } catch (JSONException e) {
                    e.printStackTrace();
                }

        }
    };

    private final Response.ErrorListener onPostsError = new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.e("PostActivity", error.toString());
        }
    };


    public void buttonOnClick(View view) {
        switch (view.getId())
        {
            case R.id.button_sapporo:
                place="Sapporo";
                location_code=location_code_sapporo;
                fetchPosts(1);
                fetchPosts(2);
                setContentView(R.layout.weather);
                break;
            case R.id.button_yokohama:
                place="Yokohama";
                location_code=location_code_yokohama;
                fetchPosts(1);
                fetchPosts(2);
                setContentView(R.layout.weather);
                break;
            case R.id.button_taipei:
                place="Taipei";
                location_code=location_code_taipei;
                fetchPosts(1);
                fetchPosts(2);
                setContentView(R.layout.weather);
                break;
            case R.id.button_vietnam:
                place="Vietnam";
                location_code=location_code_vietnam;
                fetchPosts(1);
                fetchPosts(2);
                setContentView(R.layout.weather);
                break;
            case R.id.button_GoHome:
                setContentView(R.layout.activity_main);
                break;
            case R.id.button_api:
                if(apikey.equals(apikey1)){
                apikey=apikey2;
                Toast.makeText(this, "apikey2 loaded. \n "+ apikey, Toast.LENGTH_SHORT).show();
                }else{
                apikey=apikey1;
                Toast.makeText(this, "apikey1 loaded. \n "+ apikey, Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

}

分別做了四個地點,台北,橫濱,越南跟札幌
題外話,
大概眼尖的網友會注意到我用了兩次fetchPost,我總共抓了兩個json檔案
主要是因為我第一個抓的是當日的天氣,第二個抓的是該周的天氣預報
所以會用到兩個API,才需要分開兩次抓。
好像這個網站沒有提供一次抓就可以直接抓取所有資料的方法呢...

有需要source code的話這邊有:
https://github.com/LeeHeng1121/weather_api

留言

這個網誌中的熱門文章

實作Android導覽教學(fragment)