2016년 1월 20일 수요일

[안드로이드] OpenWeather 활용, 날씨 데이터 받기 [2]










이번 포스팅에는

직접 Xml 결과물을 Android로 받아 출력 하는 것을 설명하겠습니다.


우선 AndroidManifest.xml에 아래와 같은 설정을 해주셔야 합니다.

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

그 다음, 


출력하는 곳의 xml에서 layout을 수정합니다.



activity_main.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"    
     xmlns:tools="http://schemas.android.com/tools" 
     android:layout_width="match_parent"    
     android:layout_height="match_parent" 
     android:paddingLeft="@dimen/activity_horizontal_margin"    
     android:paddingRight="@dimen/activity_horizontal_margin"    
     android:paddingTop="@dimen/activity_vertical_margin"    
     android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <TextView        
                android:id = "@+id/tv_WeatherInfo"        
                android:text="@string/hello_world"        
                android:layout_width="wrap_content"        
                android:layout_height="wrap_content" />
</ScrollView>


일단 ScrollView로 하나의 텍스트 뷰로 출력하는 부분으로 구성하였습니다.

그 다음 MainActivity.java 의 소스 입니다.
/** * Created by Warguss on 2016-01-18. */
public class MainActivity extends AppCompatActivity { public static final int THREAD_HANDLER_SUCCESS_INFO = 1; TextView tv_WeatherInfo; ForeCastManager mForeCast; String lon = "128.3910799"; // 좌표 설정 String lat = "36.1444292"; // 좌표 설정 MainActivity mThis; ArrayList<ContentValues> mWeatherData; ArrayList<WeatherInfo> mWeatherInfomation; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Initialize(); } public void Initialize() { tv_WeatherInfo = (TextView)findViewById(R.id.tv_WeatherInfo); mWeatherInfomation = new ArrayList<>(); mThis = this; mForeCast = new ForeCastManager(lon,lat,mThis); mForeCast.run(); } public String PrintValue() { String mData = ""; for(int i = 0; i < mWeatherInfomation.size(); i ++) { mData = mData + mWeatherInfomation.get(i).getWeather_Day() + "\r\n"  
+  mWeatherInfomation.get(i).getWeather_Name() + "\r\n"            
+  mWeatherInfomation.get(i).getClouds_Sort()
            +  " /Cloud amount: " + mWeatherInfomation.get(i).getClouds_Value()
            +  mWeatherInfomation.get(i).getClouds_Per() +"\r\n"            
+  mWeatherInfomation.get(i).getWind_Name()
            +  " /WindSpeed: " + mWeatherInfomation.get(i).getWind_Speed() + " mps" + "\r\n"            
+  "Max: " + mWeatherInfomation.get(i).getTemp_Max() + "℃"            
+  " /Min: " + mWeatherInfomation.get(i).getTemp_Min() + "℃" +"\r\n"            
+  "Humidity: " + mWeatherInfomation.get(i).getHumidity() + "%";

            mData = mData + "\r\n" + "----------------------------------------------" + "\r\n";
        }
        return mData;
    }

    public void DataChangedToHangeul()
    {
        for(int i = 0 ; i <mWeatherInfomation.size(); i ++)
        {
            WeatherToHangeul mHangeul = new WeatherToHangeul(mWeatherInfomation.get(i));
            mWeatherInfomation.set(i,mHangeul.getHangeulWeather());
        }
    }


    public void DataToInformation()
    {
        for(int i = 0; i < mWeatherData.size(); i++)
        {
            mWeatherInfomation.add(new WeatherInfo(
                  String.valueOf(mWeatherData.get(i).get("weather_Name")),  String.valueOf(mWeatherData.get(i).get("weather_Number")), String.valueOf(mWeatherData.get(i).get("weather_Much")),
                    String.valueOf(mWeatherData.get(i).get("weather_Type")),  String.valueOf(mWeatherData.get(i).get("wind_Direction")),  String.valueOf(mWeatherData.get(i).get("wind_SortNumber")),
                    String.valueOf(mWeatherData.get(i).get("wind_SortCode")),  String.valueOf(mWeatherData.get(i).get("wind_Speed")),  String.valueOf(mWeatherData.get(i).get("wind_Name")),
                    String.valueOf(mWeatherData.get(i).get("temp_Min")),  String.valueOf(mWeatherData.get(i).get("temp_Max")),  String.valueOf(mWeatherData.get(i).get("humidity")),
                    String.valueOf(mWeatherData.get(i).get("Clouds_Value")),  String.valueOf(mWeatherData.get(i).get("Clouds_Sort")), String.valueOf(mWeatherData.get(i).get("Clouds_Per")),String.valueOf(mWeatherData.get(i).get("day"))
            ));

        }

    }
  public Handler handler = new Handler(){
      @Override      public void handleMessage(Message msg) {
          super.handleMessage(msg);
          switch(msg.what){
              case THREAD_HANDLER_SUCCESS_INFO :
                mForeCast.getmWeather();
                mWeatherData = mForeCast.getmWeather();
                if(mWeatherData.size() ==0)
                    tv_WeatherInfo.setText("데이터가 없습니다");

                  DataToInformation(); // 자료 클래스로 저장,                  

String data = "";
                  data = PrintValue();
                  DataChangedToHangeul();
                  data = data + PrintValue();

                  tv_WeatherInfo.setText(data);
                  break;
              default:
                  break;
          }
      }
  };
}

보시면 Handler가 있는데, 이 Handler같은 경우는,

메인 UI스레드를 사용하기 위해, Message통신을 통해 일종의 동기화 작업을 하기 위한

코드 입니다.

Android 에서는 메인 UI스레드가 따로 있고, 이것을 통해서만 View에 출력되는 부분을

수정 할 수 있기에, 스레드를 사용하는 작업을 해서 View에 영향을 주실 경우 

써주셔야 합니다.

보통 일반적으로 AsyncTask를 쓰지만, 저는 일반 스레드를 사용하였기에, Handler를 썻고
,
스레드의 연산시간이 그리 크지 않는다면, Handler를 쓰지 않아도 되긴 합니다만...

써주시는게 혹시 모를 예외를 위해 좋을 듯 싶습니다.

다음으로 직접적인 Xml -> Android로 받는 작업을 하는

ForeCastManager.java 입니다.

/** * Created by Warguss on 2016-01-18. */
public class ForeCastManager extends Thread{

    String lon,lat;

    ArrayList<ContentValues> mWeatehr;
    MainActivity mContext;
    public ArrayList<ContentValues> getmWeather()
    {
        return mWeatehr;
    }

    public ForeCastManager(String lon, String lat,MainActivity mContext)
    {
        this.lon = lon ; this.lat = lat;
        this.mContext = mContext;
    }



    public ArrayList<ContentValues> GetOpenWeather(String lon,String lat)
    {

        ArrayList<ContentValues> mTotalValue = new ArrayList<ContentValues>();
        String key = "발급받은 키를 넣어주시면 됩니다.";
        try{
            URL url = new URL("http://api.openweathermap.org/data/2.5/forecast/daily?"+
                    "&APPID=" + key +
                    "&lat="+lat+
                    "&lon="+lon+
                    "&mode=xml" +
                    "&units=metric"+
                    "&cnt=" + 15            );

            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            // 위에서 생성된 URL을 통하여 서버에 요청하면 결과가 XML Resource로 전달됨
            XmlPullParser parser = factory.newPullParser();
            // XML Resource를 파싱할 parser를 factory로 생성
            parser.setInput(url.openStream(), null);
            // 파서를 통하여 각 요소들의 이벤트성 처리를 반복수행
            int parserEvent = parser.getEventType();
            while (parserEvent != XmlPullParser.END_DOCUMENT) {
              if(parserEvent == XmlPullParser.START_TAG  && parser.getName().equals("time")){
                        //시작태그의 이름을 알아냄                       
                       int checkStartTag = parserEvent;
                        ContentValues mContent = new ContentValues(); 

                    for( ; ; ) {
                        if (checkStartTag == XmlPullParser.START_TAG  && parser.getName().equals("time")) {
                            mContent.put("day", parser.getAttributeValue(null, "day"));
                        } else if (checkStartTag == XmlPullParser.START_TAG  && parser.getName().equals("symbol")) {
                            mContent.put("weather_Name", parser.getAttributeValue(null, "name"));
                            mContent.put("weather_Number", parser.getAttributeValue(null, "number"));
                        } else if (checkStartTag == XmlPullParser.START_TAG  && 
parser.getName().equals("precipitation")) {
                            mContent.put("weather_Much", parser.getAttributeValue(null, "value"));
                            mContent.put("weather_Type", parser.getAttributeValue(null, "type"));
                        } else if (checkStartTag == XmlPullParser.START_TAG  && 
parser.getName().equals("windDirection")) {
                            mContent.put("wind_Direction", parser.getAttributeValue(null, "name"));
                            mContent.put("wind_SortNumber", parser.getAttributeValue(null, "deg"));
                            mContent.put("wind_SortCode", parser.getAttributeValue(null, "code"));
                        } else if (checkStartTag == XmlPullParser.START_TAG  && parser.getName().equals("windSpeed")) {
                            mContent.put("wind_Speed", parser.getAttributeValue(null, "mps"));
                            mContent.put("wind_Name", parser.getAttributeValue(null, "name"));
                        } else if (checkStartTag == XmlPullParser.START_TAG  && 
parser.getName().equals("temperature")) {
                            mContent.put("temp_Min", parser.getAttributeValue(null, "min"));
                            mContent.put("temp_Max", parser.getAttributeValue(null, "max"));
                        } else if (checkStartTag == XmlPullParser.START_TAG  && parser.getName().equals("humidity")) {
                            mContent.put("humidity", parser.getAttributeValue(null, "value"));
                            mContent.put("humidity_unit", parser.getAttributeValue(null, "unit"));
                        } else if (checkStartTag == XmlPullParser.START_TAG  && parser.getName().equals("clouds")) {
                            mContent.put("Clouds_Sort", parser.getAttributeValue(null, "value"));
                            mContent.put("Clouds_Value", parser.getAttributeValue(null, "all"));
                            mContent.put("Clouds_Per", parser.getAttributeValue(null, "unit"));
                            mTotalValue.add(mContent);
                            break;
                        }
                        checkStartTag = parser.next();
                    }
                    
                }
                parserEvent = parser.next();
            } 
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return mTotalValue;
    }



    @Override    public void run() {
        super.run();
        if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
        }
        mWeatehr = GetOpenWeather(lon,lat);
        mContext.handler.sendEmptyMessage(mContext.THREAD_HANDLER_SUCCESS_INFO);
        //Thread 작업 종료, UI 작업을 위해 MainHandler에 Message보냄    }
}
parser.getName()을 통해 태그 이름을 확인하고, START_TAG를 통해 시작 태그인지 END 태그인지를 확인하는 작업을 수행합니다.
그리고 parser.getAttribute(값이 없을시 초기화 값, 얻고자 하는 속성 이름)


을 통해서 값을 ContentValues에 넣어 리스트화 시키게 됩니다.


또한 중요한게 











if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
        }
이 부분인데, 이 경우, AsyncTask , 메인 UI스레드에서 인터넷 접속을 권장하고 있어 
위 코드를 쓰지않을 경우 접속 에러가 뜨게 됩니다.
일반 스레드에서도 인터넷에 접속하는 것을 허용하는 문으로 꼭 넣어 주셔야 합니다.
다음으로 
받은 데이터를 클래스화 시키는
WeatherInfo.java 입니다.
/** * Created by Warguss on 2016-01-18. */public class WeatherInfo {
    String weather_Day;
    String weather_Name;
    String weather_Number;
    String weather_Much;
    String weather_Type;
    String wind_Direction;
    String wind_SortNumber;
    String wind_SortCode;
    String wind_Speed;
    String wind_Name;
    String temp_Min;
    String temp_Max;
    String humidity;
    String clouds_Value;
    String clouds_Sort;
    String clouds_Per;

    public WeatherInfo(String weather_Name, String weather_Number, String weather_Much,
                       String weather_Type, String wind_Direction, String wind_SortNumber,
                       String wind_SortCode, String wind_Speed, String wind_Name,
                       String temp_Min, String temp_Max, String humidity,
                       String clouds_Value, String clouds_Sort, String clouds_Per,String weather_Day)
    {
        this.weather_Name = weather_Name;
        this.weather_Number = weather_Number;
        this.weather_Much = weather_Much;
        this.weather_Type = weather_Type;
        this.wind_Direction = wind_Direction;
        this.wind_SortNumber = wind_SortNumber;
        this.wind_SortCode = wind_SortCode;
        this.wind_Speed = wind_Speed;

        if(wind_Name.equals("")) this.wind_Name = "No Info";
            else this.wind_Name = wind_Name;

        this.temp_Min = temp_Min;
        this.temp_Max = temp_Max;
        this.humidity = humidity;
        this.clouds_Value = clouds_Value;
        this.clouds_Sort = clouds_Sort;
        this.clouds_Per = clouds_Per;
        this.weather_Day = weather_Day;


    }

    public String getWeather_Name() {
        return weather_Name;
    }

    public String getWind_Speed() {
        return wind_Speed;
    }

    public String getWind_Name() {
        return wind_Name;
    }

    public String getTemp_Min() {
        return temp_Min;
    }

    public String getTemp_Max() {
        return temp_Max;
    }

    public String getHumidity() {
        return humidity;
    }

    public String getClouds_Value() {
        return clouds_Value;
    }

    public String getClouds_Sort() {
        return clouds_Sort;
    }

    public String getClouds_Per() {
        return clouds_Per;
    }

    public String getWeather_Day() { return weather_Day; }

    public void setWeather_Name(String weather_Name) { this.weather_Name = weather_Name; }

    public void setWind_Name(String wind_Name) { this.wind_Name = wind_Name; }

    public void setClouds_Sort(String clouds_Sort) {this.clouds_Sort = clouds_Sort;}
}

ContentValues로 받은 자료를 정보화 시키는 작업을 수행합니다.

WindName 같은 경우는 정보가 있는 경우,

없는 경우가 있기 때문에 따로 예외처리를 수행하였습니다.

다음은 한글 작업을 하기위해, 따로 조건 리스트를 만든

WeatherConditionList.java 입니다.

만약 번역이 잘못 되었더라고, 이해해 주시길...

저기서 한글만 고치시면 되니까 편하실 것으로 생각하고 있습니다.
WeatherConditionList.java
/** * Created by Warguss on 2016-01-18. */
public class WeatherConditionList {
    public ArrayList<WeatherCondition> mListSnow;
    public ArrayList<WeatherCondition> mListClearSky;
    public ArrayList<WeatherCondition> mListFew_Clouds;
    public ArrayList<WeatherCondition> mListScattered_Clouds;
    public ArrayList<WeatherCondition> mListBroken_Clouds;
    public ArrayList<WeatherCondition> mListShower_Rain;
    public ArrayList<WeatherCondition> mListRain;
    public ArrayList<WeatherCondition> mListThunderStorm;
    public ArrayList<WeatherCondition> mListMist;
    public ArrayList<WeatherCondition> mListWind;
    public ArrayList<WeatherCondition> mListWindDirection;

    public ArrayList<WeatherCondition> mListSnowToHangeul;
    public ArrayList<WeatherCondition> mListClearSkyToHangeul;
    public ArrayList<WeatherCondition> mListFew_CloudsToHangeul;
    public ArrayList<WeatherCondition> mListScattered_CloudsToHangeul;
    public ArrayList<WeatherCondition> mListBroken_CloudsToHangeul;
    public ArrayList<WeatherCondition> mListShower_RainToHangeul;
    public ArrayList<WeatherCondition> mListRainToHangeul;
    public ArrayList<WeatherCondition> mListThunderStormToHangeul;
    public ArrayList<WeatherCondition> mListMistToHangeul;
    public ArrayList<WeatherCondition> mListWindToHangeul;
    public ArrayList<WeatherCondition> mListWindDirectionToHangeul;

    public WeatherConditionList() {
        //http://openweathermap.org/weather-conditions        
          mListThunderStorm = new ArrayList<WeatherCondition>(); // 11        
          mListMist = new ArrayList<WeatherCondition>();        // 50        
          mListRain = new ArrayList<WeatherCondition>();       // 10       
          mListShower_Rain = new ArrayList<WeatherCondition>(); // 09        
          mListBroken_Clouds = new ArrayList<WeatherCondition>(); // 04        
          mListScattered_Clouds = new ArrayList<WeatherCondition>(); // 03        
          mListFew_Clouds = new ArrayList<WeatherCondition>(); // 02        
          mListClearSky = new ArrayList<WeatherCondition>(); // 01        
          mListSnow = new ArrayList<WeatherCondition>(); // 13        
          mListWind = new ArrayList<WeatherCondition>();
          mListWindDirection = new ArrayList<WeatherCondition>();
          mListThunderStormToHangeul = new ArrayList<WeatherCondition>(); // 11        
          mListMistToHangeul = new ArrayList<WeatherCondition>();        // 50        
          mListRainToHangeul = new ArrayList<WeatherCondition>();       // 10        
          mListShower_RainToHangeul = new ArrayList<WeatherCondition>(); // 09        
          mListBroken_CloudsToHangeul = new ArrayList<WeatherCondition>(); // 04        
          mListScattered_CloudsToHangeul = new ArrayList<WeatherCondition>(); // 03        
          mListFew_CloudsToHangeul = new ArrayList<WeatherCondition>(); // 02        
          mListClearSkyToHangeul = new ArrayList<WeatherCondition>(); // 01        
          mListSnowToHangeul = new ArrayList<WeatherCondition>(); // 13        
          mListWindToHangeul = new ArrayList<WeatherCondition>();
          mListWindDirectionToHangeul = new ArrayList<WeatherCondition>();
        //-------------ThunderStrom------------------//        
        mListThunderStorm.add(new WeatherCondition("200","thunderstorm with light rain"));
        mListThunderStorm.add(new WeatherCondition("201","thunderstorm with rain"));
        mListThunderStorm.add(new WeatherCondition("202","thunderstorm with heavy rain"));
        mListThunderStorm.add(new WeatherCondition("210","light thunderstorm"));
        mListThunderStorm.add(new WeatherCondition("211","thunderstorm"));
        mListThunderStorm.add(new WeatherCondition("212","heavy thunderstorm"));
        mListThunderStorm.add(new WeatherCondition("221","ragged thunderstorm"));
        mListThunderStorm.add(new WeatherCondition("230","thunderstorm with light drizzle"));
        mListThunderStorm.add(new WeatherCondition("231","thunderstorm with drizzle"));
        mListThunderStorm.add(new WeatherCondition("232","thunderstorm with heavy drizzle"));

        mListThunderStormToHangeul.add(new WeatherCondition("200","번개와 보슬비"));
        mListThunderStormToHangeul.add(new WeatherCondition("201","번개와 비"));
        mListThunderStormToHangeul.add(new WeatherCondition("202","번개와 집중 호우"));
        mListThunderStormToHangeul.add(new WeatherCondition("210","천둥"));
        mListThunderStormToHangeul.add(new WeatherCondition("211","천둥 번개"));
        mListThunderStormToHangeul.add(new WeatherCondition("212","강한 천둥 번개"));
        mListThunderStormToHangeul.add(new WeatherCondition("221","매우 강한 천둥 번개"));
        mListThunderStormToHangeul.add(new WeatherCondition("230","번개와 가벼운 이슬비"));
        mListThunderStormToHangeul.add(new WeatherCondition("231","번개와 이슬비"));
        mListThunderStormToHangeul.add(new WeatherCondition("232","번개와 집중 호우"));

        //------------Drizzle-------------------//        
        mListShower_Rain.add(new WeatherCondition("300","light intensity drizzle"));
        mListShower_Rain.add(new WeatherCondition("301","drizzle"));
        mListShower_Rain.add(new WeatherCondition("302","heavy intensity drizzle"));
        mListShower_Rain.add(new WeatherCondition("310","light intensity drizzle rain"));
        mListShower_Rain.add(new WeatherCondition("311","drizzle rain"));
        mListShower_Rain.add(new WeatherCondition("312","heavy intensity drizzle rain"));
        mListShower_Rain.add(new WeatherCondition("313","shower rain and drizzle"));
        mListShower_Rain.add(new WeatherCondition("314","heavy shower rain and drizzle"));
        mListShower_Rain.add(new WeatherCondition("321","shower drizzle"));

        mListShower_RainToHangeul.add(new WeatherCondition("300","약한 이슬비"));
        mListShower_RainToHangeul.add(new WeatherCondition("301","이슬비"));
        mListShower_RainToHangeul.add(new WeatherCondition("302","강한 이슬비"));
        mListShower_RainToHangeul.add(new WeatherCondition("310","약한 이슬비"));
        mListShower_RainToHangeul.add(new WeatherCondition("311","이슬비"));
        mListShower_RainToHangeul.add(new WeatherCondition("312","강한 이슬비"));
        mListShower_RainToHangeul.add(new WeatherCondition("313","소나기"));
        mListShower_RainToHangeul.add(new WeatherCondition("314","강한 소나기"));
        mListShower_RainToHangeul.add(new WeatherCondition("321","소나기"));
        //------------Rain----------------------//        
        mListRain.add(new WeatherCondition("500","light rain"));
        mListRain.add(new WeatherCondition("501","moderate rain"));
        mListRain.add(new WeatherCondition("502","heavy intensity rain"));
        mListRain.add(new WeatherCondition("503","very heavy rain"));
        mListRain.add(new WeatherCondition("504","extreme rain"));
        mListSnow.add(new WeatherCondition("511","freezing rain"));
        mListShower_Rain.add(new WeatherCondition("520","light intensity shower rain"));
        mListShower_Rain.add(new WeatherCondition("521","shower rain"));
        mListShower_Rain.add(new WeatherCondition("522","heavy intensity shower rain"));
        mListShower_Rain.add(new WeatherCondition("531","ragged shower rain"));

        mListRainToHangeul.add(new WeatherCondition("500","가벼운 비"));
        mListRainToHangeul.add(new WeatherCondition("501","비"));
        mListRainToHangeul.add(new WeatherCondition("502","강한 비"));
        mListRainToHangeul.add(new WeatherCondition("503","집중 호우"));
        mListRainToHangeul.add(new WeatherCondition("504","집중 호우"));
        mListSnowToHangeul.add(new WeatherCondition("511","어는 비"));
        mListShower_RainToHangeul.add(new WeatherCondition("520","가벼운 소나기"));
        mListShower_RainToHangeul.add(new WeatherCondition("521","소나기"));
        mListShower_RainToHangeul.add(new WeatherCondition("522","강한 소나기"));
        mListShower_RainToHangeul.add(new WeatherCondition("531","매우 강한 소나기"));

        //------------Snow----------------------//        
        mListSnow.add(new WeatherCondition("600","light snow"));
        mListSnow.add(new WeatherCondition("601","snow"));
        mListSnow.add(new WeatherCondition("602","heavy snow"));
        mListSnow.add(new WeatherCondition("611","sleet"));
        mListSnow.add(new WeatherCondition("612","shower sleet"));
        mListSnow.add(new WeatherCondition("615","light rain and snow"));
        mListSnow.add(new WeatherCondition("616","rain and snow"));
        mListSnow.add(new WeatherCondition("620","light shower snow"));
        mListSnow.add(new WeatherCondition("621","shower snow"));
        mListSnow.add(new WeatherCondition("622","heavy shower snow"));

        mListSnowToHangeul.add(new WeatherCondition("600","약한 눈"));
        mListSnowToHangeul.add(new WeatherCondition("601","눈"));
        mListSnowToHangeul.add(new WeatherCondition("602","거센 눈"));
        mListSnowToHangeul.add(new WeatherCondition("611","진눈 깨비"));
        mListSnowToHangeul.add(new WeatherCondition("612","급 진눈 깨비"));
        mListSnowToHangeul.add(new WeatherCondition("615","약한 눈과 비"));
        mListSnowToHangeul.add(new WeatherCondition("616","눈과 비"));
        mListSnowToHangeul.add(new WeatherCondition("620","눈"));
        mListSnowToHangeul.add(new WeatherCondition("621","소낙눈"));
        mListSnowToHangeul.add(new WeatherCondition("622","강한 소낙눈"));
        //------------Atmosphere----------------------//        
        mListMist.add(new WeatherCondition("701","mist"));
        mListMist.add(new WeatherCondition("711","smoke"));
        mListMist.add(new WeatherCondition("721","haze"));
        mListMist.add(new WeatherCondition("731","sand, dust whirls"));
        mListMist.add(new WeatherCondition("741","fog"));
        mListMist.add(new WeatherCondition("751","sand"));
        mListMist.add(new WeatherCondition("761","dust"));
        mListMist.add(new WeatherCondition("762","volcanic ash"));
        mListMist.add(new WeatherCondition("771","squalls"));
        mListMist.add(new WeatherCondition("781","tornado"));

        mListMistToHangeul.add(new WeatherCondition("701","안개"));
        mListMistToHangeul.add(new WeatherCondition("711","연기"));
        mListMistToHangeul.add(new WeatherCondition("721","실안개"));
        mListMistToHangeul.add(new WeatherCondition("731","황사 바람"));
        mListMistToHangeul.add(new WeatherCondition("741","안개"));
        mListMistToHangeul.add(new WeatherCondition("751","황사"));
        mListMistToHangeul.add(new WeatherCondition("761","황사"));
        mListMistToHangeul.add(new WeatherCondition("762","화산재"));
        mListMistToHangeul.add(new WeatherCondition("771","돌풍"));
        mListMistToHangeul.add(new WeatherCondition("781","태풍"));

        //------------clouds----------------------//        
        mListClearSky.add(new WeatherCondition("800","clear sky"));
        mListFew_Clouds.add(new WeatherCondition("801","few clouds"));
        mListScattered_Clouds.add(new WeatherCondition("802","scattered clouds"));
        mListBroken_Clouds.add(new WeatherCondition("803","broken clouds"));
        mListBroken_Clouds.add(new WeatherCondition("804","overcast clouds"));

        mListClearSkyToHangeul.add(new WeatherCondition("800","맑은 하늘"));
        mListFew_CloudsToHangeul.add(new WeatherCondition("801","구름 조금"));
        mListScattered_CloudsToHangeul.add(new WeatherCondition("802","조각 구름"));
        mListBroken_CloudsToHangeul.add(new WeatherCondition("803","조각 구름"));
        mListBroken_CloudsToHangeul.add(new WeatherCondition("804","흐림"));
 
        //-----------------Additional----------//        
        mListWind.add(new WeatherCondition("951","calm"));
        mListWind.add(new WeatherCondition("952","light breeze"));
        mListWind.add(new WeatherCondition("953","gentle breeze"));
        mListWind.add(new WeatherCondition("954","moderate breeze"));
        mListWind.add(new WeatherCondition("955","fresh breeze"));
        mListWind.add(new WeatherCondition("956","strong breeze"));
        mListWind.add(new WeatherCondition("957","high wind, near gale"));
        mListWind.add(new WeatherCondition("958","gale"));
        mListWind.add(new WeatherCondition("959","severe gale"));
        mListWind.add(new WeatherCondition("960","storm"));
        mListWind.add(new WeatherCondition("961","violent storm"));
        mListWind.add(new WeatherCondition("962","hurricane"));

        mListWindToHangeul.add(new WeatherCondition("951","바람 없음"));
        mListWindToHangeul.add(new WeatherCondition("952","남실 바람"));
        mListWindToHangeul.add(new WeatherCondition("953","산들 바람"));
        mListWindToHangeul.add(new WeatherCondition("954","건들 바람"));
        mListWindToHangeul.add(new WeatherCondition("955","흔들 바람"));
        mListWindToHangeul.add(new WeatherCondition("956","된바람"));
        mListWindToHangeul.add(new WeatherCondition("957","센바람"));
        mListWindToHangeul.add(new WeatherCondition("958","강풍"));
        mListWindToHangeul.add(new WeatherCondition("959","극심한 강풍"));
        mListWindToHangeul.add(new WeatherCondition("960","폭풍우"));
        mListWindToHangeul.add(new WeatherCondition("961","폭풍"));
        mListWindToHangeul.add(new WeatherCondition("962","허리케인"));
    }



    public class WeatherCondition {
        String id;
        String meaning;

        public WeatherCondition(String id, String meaning) {
            this.id = id;
            this.meaning = meaning;
        }
        public String getId() {
            return id;
        }
        public String getMeaning() {
            return meaning;
        }
    }
}
정말 노가다 했던것 같네요..
딱히 번역 정보가 없어서... 고생했던 작업 이었던 것 같습니다.
다음으로 
이 리스트들을 가지고
한글로 바꾸는 작업을 수행합니다.
WeatherToHangeul.java

/** * Created by Warguss on 2016-01-18. */
public class WeatherToHangeul {
    WeatherConditionList mCondition;
    ContentValues mData;
    WeatherInfo mWeatherInfo;
    
    public WeatherToHangeul(WeatherInfo tData)
    {
        mCondition = new WeatherConditionList();
        mWeatherInfo = tData;


        mWeatherInfo.setClouds_Sort(Hangeul_Weather(mWeatherInfo.clouds_Sort));
        mWeatherInfo.setWeather_Name(Hangeul_Weather(mWeatherInfo.weather_Number));
        mWeatherInfo.setWind_Name(Hangeul_Weather(mWeatherInfo.wind_Name));
    }

    public WeatherInfo getHangeulWeather()
    {
        return mWeatherInfo;
    }

    public String SnowToHangeul(String weatherNumber)
    {
        for(int i = 0; i < mCondition.mListSnow.size() ; i++)
        {
            if(mCondition.mListSnow.get(i).getId().equals(weatherNumber) ||
                    mCondition.mListSnow.get(i).getMeaning().equals(weatherNumber))
                return mCondition.mListSnowToHangeul.get(i).getMeaning();
        }

        return "";
    }
    public String ClearToHangeul(String weatherNumber)
    {
        for(int i = 0; i < mCondition.mListClearSky.size() ; i++)
        {
            if(mCondition.mListClearSky.get(i).getId().equals(weatherNumber) ||
                    mCondition.mListClearSky.get(i).getMeaning().equals(weatherNumber.toLowerCase()))
                return mCondition.mListClearSkyToHangeul.get(i).getMeaning();
        }
        return "";
    }
    public String BrokenCloudsToHangeul(String weatherNumber)
    {
        for(int i = 0; i < mCondition.mListBroken_Clouds.size() ; i++)
        {
            if(mCondition.mListBroken_Clouds.get(i).getId().equals(weatherNumber) ||
                    mCondition.mListBroken_Clouds.get(i).getMeaning().equals(weatherNumber.toLowerCase()))
                return mCondition.mListBroken_CloudsToHangeul.get(i).getMeaning();
        }
        return "";
    }
    public String FewCloudsToHangeul(String weatherNumber)
    {
        for(int i = 0; i < mCondition.mListFew_Clouds.size() ; i++)
        {
            if(mCondition.mListFew_Clouds.get(i).getId().equals(weatherNumber) ||
                    mCondition.mListFew_Clouds.get(i).getMeaning().equals(weatherNumber.toLowerCase()))
                return mCondition.mListFew_CloudsToHangeul.get(i).getMeaning();
        }
        return "";
    }
    public String ScatteredCloudsToHangeul(String weatherNumber)
    {
        for(int i = 0; i < mCondition.mListScattered_Clouds.size() ; i++)
        {
            if(mCondition.mListScattered_Clouds.get(i).getId().equals(weatherNumber) ||
                    mCondition.mListScattered_Clouds.get(i).getMeaning().equals(weatherNumber.toLowerCase()))
                return mCondition.mListScattered_CloudsToHangeul.get(i).getMeaning();
        }
        return "";
    }
    public String RainToHangeul(String weatherNumber)
    {
        for(int i = 0; i < mCondition.mListRain.size() ; i++)
        {
            if(mCondition.mListRain.get(i).getId().equals(weatherNumber) ||
                    mCondition.mListRain.get(i).getMeaning().equals(weatherNumber.toLowerCase()))
                return mCondition.mListRainToHangeul.get(i).getMeaning();
        }
        return "";
    }
    public String ShowerRainToHanGeul(String weatherNumber)
    {
        for(int i = 0; i < mCondition.mListShower_Rain.size() ; i++)
        {
            if(mCondition.mListShower_Rain.get(i).getId().equals(weatherNumber) ||
                    mCondition.mListShower_Rain.get(i).getMeaning().equals(weatherNumber.toLowerCase()))
                return mCondition.mListShower_RainToHangeul.get(i).getMeaning();
        }
        return "";
    }
    public String ThunderStromToHangeul(String weatherNumber)
    {
        for(int i = 0; i < mCondition.mListThunderStorm.size() ; i++)
        {
            if(mCondition.mListThunderStorm.get(i).getId().equals(weatherNumber) ||
                    mCondition.mListThunderStorm.get(i).getMeaning().equals(weatherNumber.toLowerCase()))
                return mCondition.mListThunderStormToHangeul.get(i).getMeaning();
        }
        return "";
    }
    public String MistToHangeul(String weatherNumber)
    {
        for(int i = 0; i < mCondition.mListMist.size() ; i++)
        {
            if(mCondition.mListMist.get(i).getId().equals(weatherNumber) ||
                    mCondition.mListMist.get(i).getMeaning().equals(weatherNumber.toLowerCase()))
                return mCondition.mListMistToHangeul.get(i).getMeaning();
        }
        return "";
    }

    public String WindToHangeul(String windName)
    {
        for(int i = 0; i < mCondition.mListWind.size() ; i++) {
            if(mCondition.mListWind.get(i).getId().equals(windName)
                    || mCondition.mListWind.get(i).getMeaning().equals(windName.toLowerCase()))
                return mCondition.mListWindToHangeul.get(i).getMeaning();
        }
        return "";
    }

    public String Hangeul_Weather(String mWeatherNumber)
    {
        String snow = SnowToHangeul(mWeatherNumber);
        String clear = ClearToHangeul(mWeatherNumber);
        String broken_Cloud = BrokenCloudsToHangeul(mWeatherNumber);
        String few_Cloud = FewCloudsToHangeul(mWeatherNumber);
        String scatter = ScatteredCloudsToHangeul(mWeatherNumber);
        String Rain = RainToHangeul(mWeatherNumber);
        String shower = ShowerRainToHanGeul(mWeatherNumber);
        String thunder = ThunderStromToHangeul(mWeatherNumber);
        String mist = MistToHangeul(mWeatherNumber);
        String wind = WindToHangeul(mWeatherNumber);


        if(!snow.equals("")) return snow;
        else if(!clear.equals("")) return clear;
        else if(!broken_Cloud.equals("")) return broken_Cloud;
        else if(!few_Cloud.equals("")) return few_Cloud;
        else if(!scatter.equals("")) return scatter;
        else if(!Rain.equals("")) return Rain;
        else if(!shower.equals("")) return shower;
        else if(!thunder.equals("")) return thunder;
        else if(!mist.equals("")) return mist;
        else if(!wind.equals("")) return wind;

        return "정보없음";
    }
}

이고 결과를 출력한다면


다음과 같은 결과를 출력할 수 있습니다~

xml같은 경우는 다양한 곳에서 사용가능한데, 

최근 이슈가 되는 공공데이터 API사이트에서도

속성값과 태그 값만 변경하시면 다양하게 적용 가능하실 것 같습니다.

이상 OpenWeather 활용 날씨 데이터 받기를 마칩니다.







전체 소스코드 파일은 GitHub에 업로드 하였습니다. https://github.com/warguss/OpenWeatherUse 주소로 가시면 받으실 수 있습니다.

댓글 26개:

  1. 날씨에 맞는 이미지를 띄우고 싶은데 레이아웃에 텍스트뷰와 추가로 이미지뷰를 사용하여 하는 방법좀 간단하게 알려주실 수 있나요? ㅠ.ㅠ

    답글삭제
  2. 일단 날씨에 따른 이미지뷰를 쓰실려면, ListView로 바꾸어야합니다. 현재 저 소스는 하나의 TextView에 모든 String을 더한 소스거든요 ㅠㅠ

    그래서 간단하게 설명 하자면, TextView -> ListView (ImageView, TextView) 로 구성된 리스트 뷰를 만들고,

    WeatherToHanguel 클래스의 Hangeul_Weather 메소드에 접근해서 날씨에 따른 이미지를 매칭하면 될 것 같습니다

    이해가 안되신다면 나중에 한번 포스팅을 해보록 할께요 ^^;;


    답글삭제
  3. 죄송한데 하나 더 여쭤보겠습니다..!
    xml값을 불러서 사용할때 START_TAG 값을 당겨서 Location의 도시명을 사용하고 싶은데
    location.location.latitude와 같이 있는 값들은 받아지는데
    location.name과 같이 보고 equals값을 location, getAttrivuteValue값을 name처럼 적용하면 안되는데 어떻게 해야 도시명을 불러서 사용할 수 있을까요?

    답글삭제
  4. 일단 [1]에서 xml 문에 대해서 보시면 getAttributeValue를 사용할 수 있는 경우는 태그 안에, 따로 지정이 되어있는 경우입니다.


    다음과 같이(부등호 <,>가 적혀지지 않아 '('로 대신합니다 ㅠ)


    (location lat =""lon=""/) 형식의 xml로만 getAttributeValue("null","lat"); 형식으로 받을 수 있습니다.


    도시 이름은 다음과 같이 "(name)도시(/name)" 로 구성 되어있지요


    도시이름을 받으실 경우 parser.nextText()를 사용하시면 받을 수 있습니다. 아래는 실행 테스트 해본 결과 소스입니다


    한번 확인해보세요~



    if(parserEvent == XmlPullParser.START_TAG && parser.getName().equals("name")) {
    city = parser.nextText();

    Log.i("cityCheck","city:"+city);
    }

    city의 자료형은 String 입니다~

    답글삭제
  5. 질문하나만 드릴게요.. 현재 날씨를 메인에 띄우고 밑에 리스트로 예보처럼 스크롤뷰를 사용하여 텍스트로 뿌려주려고 합니다.
    예제를 그대로 가져다 쓰면 스크롤 뷰에 카운트15일까지 텍스트로 나타나는데 제가 가져다 쓰면 오늘 하루치만 나오게되는데
    정보가 반복되는 구간이 public String PrintValue()구간이 아닌가요..? 초보라서 허접한 질문이지만.. 답변 부탁드립니다..!

    답글삭제
  6. 안드로이드 코딩 개초짜인데
    날씨에 맞는 이미지를 띄우는법에 대해서 설명 해주실수 있나요?

    답글삭제
    답글
    1. 처음 XML 파싱할때, weather_number의 값을 받습니다.

      이 값을 토대로, 날씨를 알 수 있습니다.

      그리고 이 값에 해당하는 부분이라면, 그 부분의 날씨 이미지 뷰를 사용하여 바꿔주시면 될 것 같네요 ^^

      아니면,

      public String Hangeul_Weather(String mWeatherNumber) 여기서 String 대신 클래스 반환으로 구성 하여,

      날씨 String과 날씨 번호 Int형을 정하고 임의로
      String : 맑음 Int : 1,
      String : 흐림 Int : 2
      이런식으로 클래스 화 지어서 저장 후 Return 방식도 생각해 볼 수 있을 것 같습니다.

      삭제
  7. 안녕하세요. 안드로이드 배우기 있는 초보인데요. 현재 실시간의 위치로 날씨정보를 받는방법이 있을까요?

    답글삭제
    답글
    1. LocationManager를 통해 위도 경도 좌표만 바꿔준다면 가능합니다 ㅎㅎ

      삭제
    2. LocationManager를 통해 위도 경도 좌표만 바꿔준다면 가능합니다 ㅎㅎ

      삭제
  8. 안드로이드 공부하는 초보 학생입니다

    날씨에 맞는 이미지도 날씨정보 옆에 같이 띄우고 싶은데.. 리스트뷰로 (이미지뷰, 텍스트뷰) 사용하는거 말고는 방법이 없을까요?
    아니면 오픈웨더에서는 이미지까지 제공은 하지않나요?ㅠㅠ

    저것들을 리스트뷰로 옮겨서 해보자니 복잡하네요..

    답글삭제
    답글
    1. 오픈웨더에서 이미지를 제공한다 하여도, 결과적으로는 리스트 뷰를 사용해야 할것입니다.

      이미지를 단순 받아와서 뿌려주는 형식이기 때문이죠..

      리스트 뷰를 한번 보시는게 쉬울 것 같네요..

      삭제
  9. 안녕하세요
    소스 정리가 너무 잘 되어있어서 도움을 많이 받았습니다.

    그런데 xml 파싱 페이지에서 현제 온도가 표시되는 부분이 어디인지 모르겠네요
    최저 온도와 최고 온도는 있고 temperature_day 이 부분이 수시로 온도가 변하기는 하지만 편차가 10도 이상 나네요
    그리고 오픈웨더 홈페이지 가서 도시 코드로 날씨 확인해보니 현제 온도가 정확히 표시가 되는데

    현제 온도 구하는 법이 있을끼요?

    답글삭제
    답글
    1. 음 글쎄요 그부분은 openwheather에서 따로 파라미터 값을 확인하여 XML요청을 하셔야 할 겁니다.

      삭제
    2. 네.. 답변 감사합니다^^

      삭제
  10. 그대로 했는데 아무거도 뜨지가 않아요ㅠㅠㅠ뭐가 문제일까요

    답글삭제
    답글
    1. 아무화면이 뜨지 않는다면,
      데이터 통신 문제인지 데이터를 화면에 뿌리는 문제인지에 대해 분석이 필요할거같습니다

      삭제
  11. 작성자가 댓글을 삭제했습니다.

    답글삭제
  12. 오픈소스 다운이 안되는데 ch409797@naver.com으로 보내주실수있으신가요 ㅜㅜ

    답글삭제
  13. 저 궁금한게 있는데요 글자 출력하는 부분이 어디에 있는건가요??

    답글삭제