iT邦幫忙

2023 iThome 鐵人賽

DAY 24
0
Mobile Development

Android Studio開發系列 第 24

【DAY 24】元件應用:API連線-2-利用API和retrofit2抓取氣象局天氣資料(下)

  • 分享至 

  • xImage
  •  

承接上篇,今天我們繼續來抓取氣象資料。

我們進入一般氣象資料的詳細頁面,會看到下圖,點選我們要的API。

再來會到這個頁面,點選try it out後就可以填入訊息了。這裡紅框的部分就是自己的金鑰。

再來會用到的就是locationName,因為我們希望可以選擇查閱哪個城市。還有elementName,主要用到MinT和MaxT兩個天氣因子。都先不用選擇,按下Execute。

我們會看到如下的json檔,待會要從其中抓取我們需要的資訊。


至於抓取的方法,我們先創建一個class,它定義我們所需要的各種數據的名稱,目的是為了連線後從氣象網站接收資訊存入這個class的變數,至於如何定義,這裡就不再贅述。下面我們看看例子:
MyResponse.class:

public class MyResponse {
    public Records records;
    public class Records
    {
        public List<Location> location;

        public class Location
        {
            public List<WeatherElement> weatherElement;

            public class WeatherElement
            {
                public List<Time> time;
                public class Time
                {
                    public Parameter parameter;
                    public class Parameter
                    {
                        public String parameterName;
                        public String parameterUnit;
                    }
                }
            }
        }
    }
}

這裡我們抓取Records中的Location,以及WeatherElement中的Time中的Parameter中的parameterName及parameterUnit,共三個數據。


主程式的部分,分為填入元素為MaxT,與MinT時的情況。
MainActivity:

public class MainActivity extends AppCompatActivity {

    //基底網址
    private static final String base="https://opendata.cwb.gov.tw/api/v1/rest/datastore/";
    //金鑰
    private static final String author="填入金鑰";
    //想要抓取的元素名稱
    private static final String element1="MaxT",element2="MinT";
    //定義變數
    private Button bts;
    private TextView tvMax,tvMin;
    private String location=city[0];
    //定義下拉式選單的內容
    static final String[] city=
            {"宜蘭縣","花蓮縣","臺東縣","澎湖縣","金門縣","連江縣","臺北市","新北市","桃園市","臺中市","臺南市",
                    "高雄市","基隆市","新竹縣","新竹市","苗栗縣","彰化縣","南投縣","雲林縣","嘉義縣","嘉義市","屏東縣"};
    static final String[] array1= {element1,element2};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //請求資料前置
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(base)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        //連接weather接口
        weather myAPIService = retrofit.create(weather.class);

        //下拉式選單設定
        Spinner spinner1;
        spinner1 = (Spinner) findViewById(R.id.spinner);
        ArrayAdapter<CharSequence> adapter = new ArrayAdapter(this,android.R.layout.simple_spinner_item,city);
        spinner1.setAdapter(adapter);

        //定義button,textview
        bts=findViewById(R.id.search);
        tvMax=findViewById(R.id.tvMax);
        tvMin=findViewById(R.id.tvMin);

        //下拉式選單監聽器
        spinner1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                location=city[i];
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {
            }
        });

        //請求資料,button按下時分別印出MaxT時,與MinT時MyResponse定義的變數
        bts.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                for(int j=0;j<2;j++)
                {
                    if(j==0)
                    {
                        myAPIService.getweather(author, location, array1[j]).enqueue(new Callback<MyResponse>() {
                            @Override
                            public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
                                Log.d("title", "請求成功");
                                
                                tvMax.setText(location + "今日最高溫度:" + response.body().records.location.get(0).weatherElement.get(0).time.get(0).parameter.parameterName
                                        + '°' + response.body().records.location.get(0).weatherElement.get(0).time.get(0).parameter.parameterUnit);
                            }

                            @Override
                            public void onFailure(Call<MyResponse> call, Throwable t) {
                                Log.d("title", "請求失敗");
                            }
                        });
                    }
                    else if(j==1)
                    {
                        myAPIService.getweather(author, location, array1[j]).enqueue(new Callback<MyResponse>() {
                            @Override
                            public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
                                tvMin.setText(location + "今日最低溫度:" + response.body().records.location.get(0).weatherElement.get(0).time.get(0).parameter.parameterName
                                        + '°' + response.body().records.location.get(0).weatherElement.get(0).time.get(0).parameter.parameterUnit);
                            }

                            @Override
                            public void onFailure(Call<MyResponse> call, Throwable t) {
                            }
                        });
                    }
                }
            }
        });
    }
}

接下來,我們要設定weather接口,直接創建一個interface,裡面分別存放三種主要元素。有沒有發現,這三種元素就是之前用紅框標起來的三格,也就是說,這個interface會代替我們將資料填入網站。
weather:

public interface weather {
    @GET("F-C0032-001")
    Call<MyResponse> getweather(
            @Query("Authorization") String myauthorization,
            @Query("locationName") String mylocationName,
            @Query("elementName") String myelementName);
}

最後就剩下layout介面了,簡單設計一下,記得元件id要配合主程式。
activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tvMax"
        android:layout_width="200dp"
        android:layout_height="50dp"
        android:text=""
        app:autoSizeTextType="none"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.335" />

    <TextView
        android:id="@+id/tvMin"
        android:layout_width="200dp"
        android:layout_height="50dp"
        android:text=""
        app:autoSizeTextType="none"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.424" />

    <Spinner
        android:id="@+id/spinner"
        android:layout_width="150dp"
        android:layout_height="50dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.547" />

    <Button
        android:id="@+id/search"
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:text="搜尋"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.65" />
</androidx.constraintlayout.widget.ConstraintLayout>

成品如下:

API和retrofit2的應用就到這裡,下一篇文章見~~


上一篇
【DAY 23】元件應用:API連線-1-利用API和retrofit2抓取氣象局天氣資料(上)
下一篇
【DAY 25】元件整合實作:製作一個簡易的氣象資訊系統-1-登入頁面及註冊頁面
系列文
Android Studio開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言