- 自由研究に戻る
- Menu表示

2012.04.21 東高根森林公園
Android http データ通信、XmlPullParserを使う
httpに関するトレーニングです(ICS4.0.3使用)。
HttpURLConnectionでWebデータ読み込みの確認
手順
下記参考サイトを参照して確認を進めます。
(1)androidでマルチスレッド(バックグランド処理)
webサイトからダウンロードする場合など所要時間が長くなる場合は、マルチスレッドにしてダウンロードします。マルチスレッドに関しては2通り紹介されてます(Androidで提供されているAsyncTaskを使う方法と、Java標準Threadクラスを使う方法)。
(2)HTTP通信でダウンロードする
HTTP通信でバイト列(テキスト, 画像データ等)をダウンロードする, HttpURLConnectionクラスの使用例が紹介されています。
紹介されているandroidのバージョンが違うのでしょう、android4.0.3でこのままではエラーになります。android.os.NetworkOnMainThreadExceptionというエラーです。http通信はmain threadではエラーになるということですので、(1)のサイトが必要になります。
(3)世界を目指せ androidアプリ開発入門 第9回 AndroidでHTTP通信を行う
AndroidManifestへ下記の記入もお忘れなく。
<uses-permission android:name="android.permission.INTERNET"> </uses-permission>
org.apache.httpを使って,HTTPプロトコルのGET, POSTメソッドの実装方法が紹介されています。
(4)Androidメモ HTTP通信
このサイトは上の(1)(2)(3)を満足してそうです。
(5)Androidメモ XML解析
(6)android XmlPullPerser XML解析
(7)XMLをパース(解析)する
(8)softbank スマートフォンサービス開発支援サイト
(9)【Android】 ライブドア Weather Hacksを使ってみる
天気予報を読み込んでいますの、確認してみます。
webサイトから読み込み、表示してみます。

Fig.1 webから読み込み
//////////////////////////////////////////////////////////
///////////プログラム@ src javaファイル///////////////////////////////////
package httpGet01.app;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
public class HttpGet01Activity extends Activity implements OnClickListener{
Handler mHandler = new Handler(); //Handlerのインスタンス生成
TextView mTextView;
String src = new String();
byte[] line = new byte[1024];
int size;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//TextView取得
mTextView = (TextView)findViewById(R.id.ThreadSample1);
//TextViewタップ時にonClick実行
findViewById(R.id.ThreadSample1).setOnClickListener(this);
}
// @Override
public void onClick(View arg0) {
// スレッド起動
(new Thread(new Runnable() {
// @Override
public void run() {
// 通常バックグランドをここに記述します
HttpURLConnection http = null;
InputStream in = null;
TextView web = (TextView)findViewById(R.id.textview);
try {
// URLにHTTP接続
URL url = new URL("http://weather.livedoor.com/forecast/rss/8/54.xml");
http = (HttpURLConnection)url.openConnection();
http.setRequestMethod("GET");
http.connect();
// データを取得
in = http.getInputStream();
// HTMLソースを読み出す
while(true) {
size = in.read(line);
if(size <= 0)
break;
src += new String(line);
}
} catch(Exception e) {
src=e.toString();
} finally {
try {
if(http != null)
http.disconnect();
if(in != null)
in.close();
} catch (Exception e) {src=e.toString();}
}
/** Handlerのpostメソッドを使ってUIスレッドに処理をdispatchします */
mHandler.post(new Runnable() {
// @Override
public void run() {
//取得したイメージをImageViewに設定
mTextView.setText(src);
}
});
}
})).start();
}
}
//////////////////////////////////////////////////////////
/////////// res xmlファイル///////////////////////////////////
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<Button
android:id="@+id/ThreadSample1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<TextView
android:id="@+id/textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="hit button key to start http" />
</LinearLayout>
XmlPullParserでデータ抽出の確認
webからxmlファイルを読み込むのはHttpURLConnectionの仕事で、任意のタグからデータを抽出する作業がXmlPullParserの仕事です。

Fig.2 XmlPullParserでデータ抽出したデータ
(Fig.1の内容とは関係ありません、下記xmlファイルをパースしたデータです)
抽出は<title>,<telop>,<description>タグ毎に抽出しています。
/////////抽出元のxmlファイル//////////
<?xml version="1.0" encoding="UTF-8" ?>
- <lwws version="livedoor Weather Web Service 1.0">
<author>livedoor Weather Team.</author>
<location area="関東" pref="茨城県" city="水戸" />
<title>茨城県 水戸 - 明日の天気</title>
<link>http://weather.livedoor.com/area/8/54.html?v=1</link>
<forecastday>tomorrow</forecastday>
<day>Tuesday</day>
<forecastdate>Tue, 01 May 2012 00:00:00 +0900</forecastdate>
<publictime>Mon, 30 Apr 2012 17:00:00 +0900</publictime>
<telop>曇り</telop>
<description>日本のはるか東に中心を持つ高気圧が東日本に張り出しています。一方、東シナ海には前線が停滞し、九州の南に低気圧が発生して東に進んでいます。現在、関東地...<br />[PR]<a href="http://weather.livedoor.com/indexes/cloth_wash/?r=rest_pr">きょうは洗濯できるかな?</a></description>
- <image>
<title>曇り</title>
//////////////////////////////////////////////////////////
/////////// srcファイル、プログラム@にparserを追加///////
先述の参考サイト(9)の確認になってしまいました。
http://weather.livedoor.com/forecast/webservice/rest/v1?city=54&day=tomorrowからxmlファイルをダウンロードし、parserに渡します。
package httpGet01.app;
import java.io.InputStream;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.StringTokenizer;
import org.xmlpull.v1.XmlPullParser;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Xml;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
public class HttpGet01Activity extends Activity implements OnClickListener{
Handler mHandler = new Handler(); //Handlerのインスタンス生成
TextView mTextView;
String src = new String();
byte[] line = new byte[1024];
int size;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//TextView取得
mTextView = (TextView)findViewById(R.id.ThreadSample1);
//TextViewタップ時にonClick実行
findViewById(R.id.ThreadSample1).setOnClickListener(this);
}
// @Override
public void onClick(View arg0) {
// スレッド起動
(new Thread(new Runnable() {
// @Override
public void run() {
// 通常バックグランドをここに記述します
int intEventType = -1;
String strParserName = "";
StringTokenizer objToken = null;
String strGettingTitle = "";
String strGettingTelop = "";
String strGettingDiscription = "";
HttpURLConnection http = null;
InputStream in = null;
TextView web = (TextView)findViewById(R.id.textview);
try {
// URLにHTTP接続
URL url = new URL("http://weather.livedoor.com/forecast/rss/8/54.xml");
http = (HttpURLConnection)url.openConnection();
http.setRequestMethod("GET");
http.connect();
// データを取得
in = http.getInputStream();
// HTMLソースを読み出す
while(true) {
size = in.read(line);
if(size <= 0)
break;
src += new String(line);
}
} catch(Exception e) {
src=e.toString();
} finally {
try {
if(http != null)
http.disconnect();
if(in != null)
in.close();
} catch (Exception e) {src=e.toString();}
}
/** Handlerのpostメソッドを使ってUIスレッドに処理をdispatchします */
mHandler.post(new Runnable() {
// @Override
public void run() {
//取得したイメージをImageViewに設定
mTextView.setText(src);
}
});
try{
//取得XMLのURIを設定--ここからをプログラム@に追加
//uri += "?city=" + id + "&day=tomorrow";
URL uri = new URL("http://weather.livedoor.com/forecast/webservice/rest/v1?city=54&day=tomorrow");
//XML取得
http = (HttpURLConnection)uri.openConnection();
http.setRequestMethod("GET");
http.connect();
// データを取得
in = http.getInputStream();
//XMLから情報を抽出
XmlPullParser parser = Xml.newPullParser();
parser.setInput(in,"UTF-8");
while(intEventType != XmlPullParser.END_DOCUMENT){
switch (intEventType){
case XmlPullParser.START_TAG:
strParserName = parser.getName() ;
if(strParserName.equals("title") && strGettingTitle.equals("")){
strGettingTitle = parser.nextText();
}
if(strParserName.equals("telop") && strGettingTelop.equals("")){
strGettingTelop = parser.nextText();
}
if(strParserName.equals("description") && strGettingDiscription.equals("")){
strGettingDiscription = parser.nextText();
}
}
if(!strParserName.equals("") && !strGettingTelop.equals("") && !strGettingDiscription.equals("")){
break;
}
intEventType = parser.next();
}
//取得データを画面に表示
src=strGettingTitle + "\n" + strGettingTelop + "\n" + strGettingDiscription;
}catch(Exception e){
src=e.toString();
}finally{
}
mHandler.post(new Runnable() {
// @Override
public void run() {
//取得したイメージをImageViewに設定
mTextView.setText(src);
}
});
}
})).start();
}
}