관리 메뉴

꿈 많은 개발자가 되자! Tae-hwan

Android 구글 날씨 파싱(XmlPullParser 사용) 본문

Android Dev/Dev

Android 구글 날씨 파싱(XmlPullParser 사용)

taehwan 2011.10.06 15:28
크리에이티브 커먼즈 라이선스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시 2.0 대한민국 라이선스에 따라 이용하실 수 있습니다.
다음의 글이 오래되어 새로작성한 Android ListView 사용하기를 참고하세요.



아래 XmlPullParser.nextText()사용에 주의해야 한다는 블로그 글입니다!^^

아샌에서 개발 하실 경우와 그외에 사용하실 때 참고 한번 해보시는게 좋을 것 같아 링크를 추가했습니다!^^
 
http://android-developers-kr.blogspot.com/2012/01/xmlpullparsernexttext.html 

 더 이상 구글에서 날씨 정보를 제공하지 않습니다. 그래서 아래의 날씨 파싱하기는 불가능합니다. 파싱 방법을 다른 곳에 적용해보세요^^;;

구글 날씨 정보를 파싱하는 소스코드 입니다.


"http://www.google.com/ig/api?hl=ko&weather=seoul" 로 접속하여 xml을 받아오고 파싱합니다.
파싱한 후 Android의 ListView에 뿌려줍니다.
XmlPullParser를 사용하여 파싱합니다. 


activity 메인 소스코드 
AsyncTask를 사용하여 google에서 제공하는 날씨 정보 xml을 가지고 옵니다.
package com.tae.sadcafek.parsingweather;

import java.util.ArrayList;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ListView;

public class ParsingWeatherActivity extends Activity {
	Parser parser;
	WeatherAdapter adapter;
	ListView list;
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
        
		list = (ListView) findViewById(R.id.list);
        
		parser = new Parser(); //파서를 객체 생성합니다.(구글 접속하여 xml 정보를 가지고 오고 파싱을 합니다.)
		new WeatherAsync().execute(null, null, null); //async Task를 사용하여 Thread 처리합니다.
	}
    
	public class WeatherAsync extends AsyncTask<String, String, ArrayList<WeatherForecast>> {

		@Override
		protected ArrayList<weatherforecast> doInBackground(String... params) {
		return parser.connectWeather(); //파싱 정보를 ArrayList로 가지고 옵니다.
		}
     
		@Override
		protected void onPostExecute(ArrayList<weatherforecast> result) {
			adapter = new WeatherAdapter(ParsingWeatherActivity.this, 0, result);
			list.setAdapter(adapter);
		}
	}
}

날씨 정보를 받아서 저장하기 위한 클래스입니다.

package com.tae.sadcafek.parsingweather;

public class WeatherForecast {
	public String dayOfWeek; //날자 정보
	public String high; //최고 온도
	public String low; //최저 온도
	public String icon; //icon의 url 경로
	public String condition; //날씨 정보
}

파싱을 처리하는 부분입니다.

package com.tae.sadcafek.parsingweather;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import android.util.Log;

public class Parser {
	private String TAG = "Parser";
 
	ArrayList connectWeather() {
	InputStream is = null;
	try {
		String url = "http://www.google.com/ig/api?hl=ko&weather=seoul"; //URL 을 String로 저장합니다.
		URL targetURL = new URL(url); //URL을 생성합니다.
   
		is = targetURL.openStream(); //open Stream을 사용하여 InputStream을 생성합니다.
   
		//XmlPullParser를 사용하기 위해서 생성합니다.
		XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); 
		XmlPullParser parser = factory.newPullParser();
    
		parser.setInput(is, "euc-kr"); //euc-kr로 언어를 설정합니다. utf-8로 하니깐 깨지더군요
		return parseWeather(parser); //받아온 xml을 파싱하여서 리턴해줍니다.
   
	} catch (MalformedURLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (XmlPullParserException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} finally {
		try {
			is.close(); //inputstream을 닫습니다.
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
  
	return null;  
 }

google에서 날씨 정보를 받아오고 xml을 파싱을 하는 부분입니다.
ArrayList<weatherforecast> parseWeather(XmlPullParser parser) throws XmlPullParserException, IOException {
	ArrayList<weatherforecast> parseWeather = new ArrayList<weatherforecast>();
	String tag; //tag를 받기위한 임시 변수입니다.
	WeatherForecast wf = null;
	int parserEvent = parser.getEventType();
	while(parserEvent != XmlPullParser.END_DOCUMENT) {
		switch(parserEvent) {
			case XmlPullParser.END_TAG: //xml의  이부분을 만나면 실행되게 됩니다.
			tag = parser.getName();
			//google에서 적용해주는 xml 중 forecast_conditions 를 만나면 ArrayList에 추가하게 됩니다. 
			if(tag.compareTo("forecast_conditions") == 0) {
				parseWeather.add(wf);
			}
			break;
			case XmlPullParser.START_TAG: //xml의 <> 부분을 만나게 되면 실행되게 됩니다.
			tag = parser.getName();
			if(tag.compareTo("forecast_conditions") == 0) { //시작 부분을 만나면 객체를 생성합니다.
				wf = new WeatherForecast();
			} else if(wf != null && tag.compareTo("day_of_week") == 0) { //날짜 정보를 가져옵니다.
				//<condition data="부분적으로 흐림">
				//에서 data 부분에서 값을 가져오기 위해서 getAttributeValue를 사용합니다.
				wf.dayOfWeek = parser.getAttributeValue(null, "data");
				Log.d(TAG, wf.dayOfWeek);
			} else if(wf != null && tag.compareTo("low") == 0) { //최저 온도 값
				wf.low = parser.getAttributeValue(null, "data"); 
			} else if(wf != null && tag.compareTo("high") == 0) { //최고 온도 값
				wf.high = parser.getAttributeValue(null, "data");
			} else if(wf != null && tag.compareTo("icon") == 0) { //url정보를 가져옵니다.
				wf.icon = parser.getAttributeValue(null, "data");
			} else if(wf != null && tag.compareTo("condition") == 0) { //날시 정보를 가져옵니다.
				wf.condition = parser.getAttributeValue(null, "data");
			}
			break;
		}
		parserEvent = parser.next(); //다음 태그를 읽어 들입니다.
	}
	return parseWeather; //완료되면 arrayList를 리턴합니다.
 }
}
 
ListView에 뿌려주는 코드입니다.
package com.tae.sadcafek.parsingweather;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class WeatherAdapter extends ArrayAdapter<weatherforecast>{
	private View v; //view를 선언합니다.
	private ViewHolder holder; //holder를 선언합니다.

	public WeatherAdapter(Context context, int resource, List<WeatherForecast> objects) {
		super(context, resource, objects);
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		if (convertView == null) { //한번만 선언하기 위해서 convertView가 null일때 실행 합니다.
			LayoutInflater inflater = LayoutInflater.from(getContext());
			v = inflater.inflate(R.layout.list_item_1, null); //리스트 뷰의 아이템 리스트를 불러옵니다.
			holder = new ViewHolder(); //Holder를 선언합니다.
			//각 textView와 ImageView를 연결합니다. 
			holder.dayOfWeek = (TextView) v.findViewById(R.id.dayOfWeek);
			holder.high = (TextView) v.findViewById(R.id.high);
			holder.low = (TextView) v.findViewById(R.id.low);
			holder.condition = (TextView) v.findViewById(R.id.condition);
			holder.imgView = (ImageView) v.findViewById(R.id.imgView);
			v.setTag(holder); //setTag를 사용하여 임시 저장합니다.
		} else { //convertView가 null이 아니기 때문에 다음을 실행 합니다.
			v = convertView;
			holder = (ViewHolder) v.getTag();
		}

		final WeatherForecast wf = getItem(position); //포지션 별로 값을 채워 줍니다.
		holder.dayOfWeek.setText(wf.dayOfWeek);
		holder.high.setText(wf.high);
		holder.low.setText(wf.low);
		holder.condition.setText(wf.condition); //Image를 Load하는데 오랜 시간이 걸리기 때문에 async task를 사용했습니다. 
		new ImageAsync(holder.imgView).execute(wf.icon);
 
		return v;
		}
	}

	//AsyncTask를 사용하여 이미지를 호출 합니다.
	class ImageAsync extends AsyncTask<String, String, ImageView> {
        	Bitmap bm; 
		ImageView mImg;
 
		ImageAsync(ImageView img) {
		mImg = img; //imageView를 복사합니다.
	}

	@Override
        //background에서 이미지 다운을 실행합니다. 
	protected ImageView doInBackground(String... params) {
	try {
		//url을 불러옵니다. 
		//<icon data="/ig/images/weather/sunny.gif"> 형태이기 때문에 아래와같이  
		//www.google.com을 붙여줍니다. 
		URL url = new URL("http://www.google.com" + params[0]); 
		URLConnection connection = url.openConnection(); //url로 연결합니다.
		connection.connect();
		InputStream is = connection.getInputStream();
		BufferedInputStream bis = new BufferedInputStream(is); //버퍼에 복사합니다.
		bm = BitmapFactory.decodeStream(bis); //비트맵으로 복사합니다.
		bis.close();
		is.close();
	} catch (IOException e) {
		// TODO: handle exception
	}
	return null;
	}
 
	@Override
        //백그라운드로 다운 받은 이미지를 mImg에 setImageBitmap 합니다. 
	protected void onPostExecute(ImageView imgView) {
		mImg.setImageBitmap(bm);
	}
}

//holder하기 위한 뷰를 미리 생성해둡니다.
class ViewHolder {
	TextView dayOfWeek;
	TextView high;
	TextView low;
	TextView condition;
	ImageView imgView;
}
 
xml item 리스트 xml입니다.







 

xml main 레이아웃 입니다.




 
이상입니다. 

ParsingWeather.zip




저작자 표시
신고
AD
0 Comments
댓글쓰기 폼