티스토리 뷰

위치정보로 날씨 정보를 가져오기 위해서는 우선 GeoPoint로 지역정보를 가져와야합니다.
이를 위해서는 Geocoder를 이용합니다.

지역->GeoPoint 를 지오코딩(Geocoding)이라고 하고,
GeoPoint->지역 을 역 지오코딩(Reverse geocoding)이라고 합니다.

여기서는 역 지오코딩을 이용합니다.

Geocoder의 getFromLocation()을 이용하여 Address 객체를 받아올 수 있습니다.

※ 주의 : 아시다시피 GeoPoint의 위도와 경도 값은 마이크로 값이므로 int형 입니다.
하지만 getFromLocation에서 사용되는 위도와 경도는 실제 값으로 double형입니다.
그래서 10^6으로 나누어서 인자를 넣어줘야 합니다.

Address 객체를 통해 지역 값을 가져오면 그것을 통해 구글 날씨 API에 접근하게 됩니다.
URL 객체를 이용하여 해당 페이지의 xml을 가져올 수 있고,
그것을 파싱하여 필요한 정보만을 뽑아내게 됩니다.

파싱에 관한 건 안드로이드사이드의 나야정수님 강좌를 참조하였습니다.

실행 결과와 소스 코드는 아래와 같습니다.

<test.java>
package skim.apod;

import android.app.Activity;
import android.location.Geocoder;
import android.os.Bundle;
import android.widget.TextView;

import com.google.android.maps.GeoPoint;

public class test extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
Geocoder t_Geocoder = new Geocoder(this);
// for getFromLocation()
// getFromLocation()함수를 이용하여 GeoPoint값을 지역 값으로 가져오는데 필요하다.
// 오버로딩된 생성자의 두 번째 인자를 사용하여 언어 선택 가능하다(Locale).

GeoPoint t_GeoPoint = new GeoPoint(37517292, 127037187);
// location value for transform
// 변환하고자 하는 GeoPoint 값이다.
// http://www.mygeoposition.com/ 에서 값을 얻을 수 있다.


GeoToWeather gtw = new GeoToWeather(t_Geocoder, t_GeoPoint);
// for getWeather()
Weather t_Weather = gtw.getWeather();
// GeoPoint를 GeoCoder로 Reverse Geocoding한다.
// 해당 지역의 날씨 정보를 Google API를 이용하여 Parsing한 후 Weather형으로 반환한다.
String tStr = "날씨 = " + t_Weather.m_sCurrentState
+ "\n화씨 = " + t_Weather.m_nTempF
+ "\n섭씨 = " + t_Weather.m_nTempC
+ "\n지역 = " + t_Weather.m_sRegion
+ "\n습도 = " + t_Weather.m_sHumidity
+ "\n바람 = " + t_Weather.m_sWindCondition;

TextView t_textview = new TextView(this);
t_textview.setText(tStr);
t_textview.setTextSize(30);
setContentView(t_textview);
}
}


<GeoToWeather.java>
package skim.apod;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

import android.location.Address;
import android.location.Geocoder;

import com.google.android.maps.GeoPoint;

public class GeoToWeather {

private Geocoder geoCoder;
private GeoPoint geoPoint;
public GeoToWeather(Geocoder t_gc, GeoPoint t_gp)
{
geoCoder = t_gc;
geoPoint = t_gp;
}
public Weather getWeather()
{
List<Address> tList=null;
        try { 
tList = geoCoder.getFromLocation((double)geoPoint.getLatitudeE6()/1000000, 
      (double)geoPoint.getLongitudeE6()/1000000, 5);
} catch (IOException e) {
}
// geocoder의 getFromLocation()을 이용하여 Reverse Geocoding(Geopoint->주소)한다.
// getFromLocation()의 인자로 들어가는 latitude와 longitude는 마이크로 값이 아니므로
// 10^6을 나누어 인자로 넣어준다.

Address tAddr = tList.get(0);
Weather dataWeather = new Weather();
        dataWeather.m_sRegion = tAddr.getLocality();
// 지역명을 가지고 온다. Geocoder 생성자의 두 번째 이자를 특정한 Locale로 주었을 경우에는
        // 해당 언어로 지역명이 나온다. 영어가 Default이다.
        
        
        
        // 아래는 실제 파싱하는 부분이다.
        XmlPullParserFactory factory = null;
try{
factory = XmlPullParserFactory.newInstance();

factory.setNamespaceAware(true);
XmlPullParser xpp = null;

xpp = factory.newPullParser();

String connectUrl = "http://www.google.co.kr/ig/api?weather="
+ dataWeather.m_sRegion;
// 해당 지역의 url을 설정한다.
URL UrlRecWeather = null;
UrlRecWeather = new URL(connectUrl);

InputStream in;
in = UrlRecWeather.openStream();

xpp.setInput(in, "euc-kr");

ReceiveParsing getParse = new ReceiveParsing(dataWeather);

getParse.proceed(xpp);
}
catch(Exception ex)
{

}
return dataWeather;
}
public void chageGeoPoint(GeoPoint t_gp)
{
geoPoint = t_gp;
}
// 파싱하는 클래스. 내부클래스로 삽입
class ReceiveParsing {
Weather dataWeather;
public ReceiveParsing(Weather t_dW)
{
dataWeather = t_dW;
}

void proceed(XmlPullParser ReceiveStream) {

boolean bcurrent_condition = false;

try {

String sTag;

int eventType = ReceiveStream.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {

// Wait(10);
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
break;

case XmlPullParser.END_DOCUMENT:
break;

case XmlPullParser.START_TAG:
// items.add(xpp.getAttributeValue(0));
sTag = ReceiveStream.getName();

if (sTag.equals("current_conditions")) {
bcurrent_condition = true;

if (bcurrent_condition == true) {
if (sTag.equals("condition")) {
String sValue = ReceiveStream.getAttributeValue(0);
dataWeather.m_sCurrentState = sValue;
} else if (sTag.equals("temp_f")) {
String sValue = ReceiveStream.getAttributeValue(0);
dataWeather.m_nTempF = Integer.parseInt(sValue);
} else if (sTag.equals("temp_c")) {
String sValue = ReceiveStream.getAttributeValue(0);
dataWeather.m_nTempC = Integer.parseInt(sValue);
} else if (sTag.equals("humidity")) {
String sValue = ReceiveStream.getAttributeValue(0);
dataWeather.m_sHumidity = sValue;
} else if (sTag.equals("wind_condition")) {
String sValue = ReceiveStream.getAttributeValue(0);
dataWeather.m_sWindCondition = sValue;
}
}
break;

case XmlPullParser.END_TAG:
sTag = ReceiveStream.getName();

if (sTag.equals("current_conditions")) {
bcurrent_condition = false;
break;

case XmlPullParser.TEXT:
break;
}

eventType = ReceiveStream.next();
}
} catch (Exception e) {

}  
}
}


}

// 날씨 형에 관한 구조를 지니는 구조체 형 클래스
class Weather {
int m_nTempF = 0;
int m_nTempC = 0;
String m_sRegion = "Not";
String m_sCurrentState = "Not";
String m_sHumidity = "Not";
String m_sWindCondition = "Not";
}

<manifest>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="skim.apod"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".test"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    <uses-library android:name="com.google.android.maps">
</uses-library>
</application>
    <uses-sdk android:minSdkVersion="7" />

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest> 
(추가할 부분 굵게 표시하였습니다.)


<실행결과>

댓글