Android Studio で Livedoor の お天気Webサービス(JSON) を読み込んで ListView に表示する

Livedoor の お天気Webサービス はこの手のテストに最適な API です。結果は JSON フォーマットで返されるので、 Google Gson を使用します。

※ Google Gson のオンラインドキュメント

読み込んだ後、SharedPreferences で書き込んでいます。


 
package app.lightbox.winofsql.jp.weather;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import com.google.gson.Gson;

public class MainActivity extends Activity {

	private ArrayAdapter<PinpointLocation> arrayMyData = null;
	private HttpGet hg = new HttpGet();

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

		// WEBアクセス( HttpGet )
		Button button = (Button) this.findViewById(R.id.button);
		button.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				new AsyncTask<String, Void, String>() {

					// 非同期処理
					@Override
					protected String doInBackground(String... params) {
						String result = null;
						HttpGet hg = new HttpGet();
						result =
								hg.execute(
										params[0],
										params[1],
										null
								);

						return result;
					}

					// UI スレッド処理
					@Override
					protected void onPostExecute(String json) {
						super.onPostExecute(json);

						// ListView のインスタンスを取得
						ListView listview = (ListView) MainActivity.this.findViewById(R.id.listView);
						// 専用クラス用
						arrayMyData = new ArrayAdapter<PinpointLocation>(
								MainActivity.this,
								android.R.layout.simple_list_item_1,
								android.R.id.text1
						);

						Gson gson = new Gson();
						Weather weatherData = gson.fromJson(json, Weather.class);

						// Weather クラス内の配列部分をセット
						arrayMyData.addAll(weatherData.pinpointLocations);
						listview.setAdapter(arrayMyData);

						String reJson = gson.toJson(weatherData);
						SharedPreferences sp = getSharedPreferences("lightbox", MODE_PRIVATE);
						SharedPreferences.Editor editor = sp.edit();
						editor.putString("json", reJson);
						editor.commit();

					}
				}.execute("http://weather.livedoor.com/forecast/webservice/json/v1?city=270000", "utf-8");
			}
		});

		// クリックした時のイベント作成
		ListView listview = (ListView) MainActivity.this.findViewById(R.id.listView);
		listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				// クリックされたビューの内部データ
				Object data = (Object) parent.getItemAtPosition(position);

				PinpointLocation myData = (PinpointLocation) data;
				Log.i("lightbox", "url:" + myData.link);

				// ブラウザの呼び出し
				callBrowser(myData.link);

			}
		});
	}

	private void callBrowser( String url ) {
		// ブラウザの呼び出し
		Uri uri = Uri.parse(url);
		Intent intent = new Intent(Intent.ACTION_VIEW, uri);
		if (intent.resolveActivity(getPackageManager()) != null) {
			startActivity(intent);
			return;
		}

		// 対応するアプリが無い
		Toast.makeText(
				MainActivity.this,
				"ブラウザを呼び出せません",
				Toast.LENGTH_LONG
		).show();
		return;

	}

	public class PinpointLocation {
		String link;
		String name;

		@Override
		public String toString() {
			return name;
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.menu_main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int id = item.getItemId();

		if (id == R.id.lv_action1) {
			if ( arrayMyData == null || arrayMyData.getCount() == 0 ) {
				Toast.makeText(MainActivity.this,"データがありません",Toast.LENGTH_LONG).show();
				return true;
			}

			PinpointLocation data = new PinpointLocation();
			// 久留米市
			data.name = "\u4e45\u7559\u7c73\u5e02";
			data.link = "http://weather.livedoor.com/area/forecast/4020300";
			arrayMyData.insert(data,3);

			return true;
		}

		if (id == R.id.lv_action2) {
			if ( arrayMyData == null || arrayMyData.getCount() == 0 ) {
				Toast.makeText(MainActivity.this,"データがありません",Toast.LENGTH_LONG).show();
				return true;
			}

			PinpointLocation data = null;
			int count = arrayMyData.getCount();
			for ( int i = 0; i < count; i++ ) {
				data = arrayMyData.getItem(i);
				Log.i("lightbox",data.name + ":" + data.link);
			}

			return true;
		}


		return super.onOptionsItemSelected(item);
	}
}

Common Intents ( Web Browser ) | Android Developers

JSON 用 Weather クラス
package app.lightbox.winofsql.jp.weather;


public class Weather {

	class Text {
		String text;
		String publicTime;
	}

	class Location {
		String city;
		String area;
		String prefecture;
	}

	class IntTest {
		ImageSize image;
	}

	class ImageSize {
		int width;
		int height;
	}

	MainActivity.PinpointLocation[] pinpointLocations;
	Location location;
	IntTest copyright;
	Text description;

	// Getter と Setter で処理する
	private String publicTime;

	String getPublicTime() {
		return publicTime.substring(0, 10);
	}
	void setPublicTime(String publicTime) {
		this.publicTime = publicTime;
	}

}



HttpGet.java
package app.lightbox.winofsql.jp.weather;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;

public class HttpGet {

	// **********************************************
	// コンストラクタ
	// **********************************************
	public HttpGet() {
	}

	// **********************************************
	// 指定した URL へ 任意の charset で処理
	// **********************************************
	public String execute(String targetUrl,String targetCharset,Map<String,String> params) {

		StringBuffer web_data = new StringBuffer();

		try {
			// **********************************************
			// Query String の作成( 必要無ければ引数を null とする )
			// **********************************************
			String data = "";
			if ( params != null ) {
				Iterator<String> it =  params.keySet().iterator();
				String key = null;
				String value = null;
				while(it.hasNext()) {
					key = it.next().toString();
					value = params.get(key);
					if ( !data.equals("") ) {
						data += "&";
					}
					data += key + "=" + URLEncoder.encode(value, targetCharset) ;
				}
				if ( !data.equals("") ) {
					targetUrl = targetUrl + "?" + data;
				}
			}

			// **********************************************
			// インターネットへの接続
			// **********************************************
			// 読み込む WEB上のターゲット
			URL url = new URL(targetUrl);
			// 接続オブジェクト
			HttpURLConnection http = (HttpURLConnection)url.openConnection();
			// GET メソッド
			http.setRequestMethod("GET");
			// 接続
			http.connect();

			// **********************************************
			// ストリームとして読み込む準備
			// **********************************************
			// 以下読み込み3点セット InputStream / InputStreamReader / BufferedReader
			InputStream input_stream = http.getInputStream();
			// UTF-8 でリーダーを作成
			InputStreamReader input_stream_reader = new InputStreamReader(input_stream, targetCharset);
			// 行単位で読み込む為の準備
			BufferedReader buffered_reader = new BufferedReader(input_stream_reader);

			// **********************************************
			// 行の一括読み込み
			// **********************************************
			String line_buffer = null;
			// BufferedReader は、readLine が null を返すと読み込み終了
			while ( null != (line_buffer = buffered_reader.readLine() ) ) {
				web_data.append( line_buffer );
				web_data.append( "\n" );
			}

			// **********************************************
			// 接続解除
			// **********************************************
			http.disconnect();
		}
		catch(Exception e) {
			// 失敗
			System.out.println( e.getMessage());
		}
		return web_data.toString();
	}
}


メニュー定義
<menu xmlns:android="http://schemas.android.com/apk/res/android"
	  xmlns:tools="http://schemas.android.com/tools"
	  tools:context=".MainActivity">
	<item
		android:id="@+id/lv_action1"
		android:title="処理1"
		android:orderInCategory="100"
		android:showAsAction="never"/>
	<item
		android:id="@+id/lv_action2"
		android:title="処理2"
		android:orderInCategory="100"
		android:showAsAction="never"/>
	<item
		android:id="@+id/lv_action3"
		android:title="処理3"
		android:orderInCategory="100"
		android:showAsAction="never"/>
	<item
		android:id="@+id/lv_action4"
		android:title="処理4"
		android:orderInCategory="100"
		android:showAsAction="never"/>
	<item
		android:id="@+id/lv_action5"
		android:title="処理5"
		android:orderInCategory="100"
		android:showAsAction="never"/>

</menu>