AsyncTaskを利用した通信を利用して、カレンダーを作ってみよう。

今回はカレンダーAPIを提供してくれている以下のサイトをご利用させていただく。

カレンダーネット
http://calendar-service.net/

上記サイトに

http://calendar-service.net/cal?start_year=2017&start_mon=1&end_year=2017&end_mon=12&year_style=normal&month_style=ja&wday_style=ja&format=csv

のリクエストを投げると

年,月,日,年号,和暦,曜日,曜日番号,祝日名
2017,1,1,平成,29,日,0,元日
2017,1,2,平成,29,月,1,振替休日
2017,1,3,平成,29,火,2,
2017,1,4,平成,29,水,3,
2017,1,5,平成,29,木,4,
略

というカレンダーのCSVデータをレスポンスとして受け取れる。(レスポンスの文字コードはEUC-JP)
このデータを利用してリストビューでカレンダーを作ってみよう。なお通信中はプログレスバーを使って通信していることをユーザーに伝えること。

[実行例]
●スタート画面

●取得ボタンを押すと通信を開始し通信が終わるとリストビューが表示される。

[作例]

●AndroidManifest.xml(uses_permissionの1行を挿入する)

    <uses-permission android:name="android.permission.INTERNET"/>

●activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <ProgressBar
        android:id="@+id/pb"
        style="@android:style/Widget.DeviceDefault.Light.ProgressBar.Small"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:visibility="gone"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="8dp"
        android:layout_marginLeft="8dp" />

    <Button
        android:id="@+id/button"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginTop="7dp"
        android:onClick="btClick"
        android:text="取得"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/pb"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp" />

    <ListView
        android:id="@+id/lv"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toBottomOf="@+id/button"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="8dp" />
</android.support.constraint.ConstraintLayout>

●MyTask.java


import android.content.Context;
import android.os.AsyncTask;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;


public class MyTask extends AsyncTask<String,Void,List<String>> {
    private ListView lv;
    private ArrayAdapter<String> adapter;
    private ProgressBar pb;
    private List<String> list;
    private Context c;

    public MyTask(Context c){
        this.c=c;
        MainActivity activity=(MainActivity)c;
        lv=(ListView)activity.findViewById(R.id.lv);
        pb=(ProgressBar)activity.findViewById(R.id.pb);

    }
    @Override
    protected void onPreExecute() {
        pb.setVisibility(ProgressBar.VISIBLE);
        list=new ArrayList<>();
    }

    @Override
    protected void onPostExecute(List<String> list) {

        adapter=new ArrayAdapter<>(c,android.R.layout.simple_list_item_1,list);
        lv.setAdapter(adapter);
        pb.setVisibility(ProgressBar.GONE);
    }
    
    @Override
    protected List<String> doInBackground(String... params) {


        try {
            URL url=new URL(params[0]);
            HttpURLConnection con=(HttpURLConnection)url.openConnection();
            con.setRequestMethod("GET");

            InputStream is=con.getInputStream();
            InputStreamReader isr=new InputStreamReader(is,"EUC-JP");
            BufferedReader br=new BufferedReader(isr);
            String line;
            while((line=br.readLine()) != null){
                if(line.startsWith("年")){
                    continue;
                }
                //第二引数負で最後のデータが空でも空文字として取得する
                String[] data=line.split(",",-1);
                //年,月,日,年号,和暦,曜日,曜日番号,祝日名
                String str=String.format("%s月%s日(%s) %s",data[1],data[2],data[5],data[7]);
                list.add(str);

            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return list;
    }
}

●MainActivity.java

package com.example.mjpurin.calendarapp;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }
    public void btClick(View v){
        MyTask mt=new MyTask(this);
        mt.execute("http://calendar-service.net/cal?start_year=2017&start_mon=1&end_year=2017&end_mon=12&year_style=normal&month_style=ja&wday_style=ja&format=csv");
    }
}