블로그 이미지
Kanais
Researcher & Developer 퍼즐을 완성하려면 퍼즐 조각들을 하나 둘씩 맞춰나가야 한다. 인생의 퍼즐 조각들을 하나 둘씩 맞춰나가다 보면 인생이란 퍼즐도 완성되는 날이 오려나...?

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Notice

05-21 06:56

Recent Post

Recent Comment

Recent Trackback

Archive

2016. 6. 22. 19:49 Programming/Android



 운영체제 : Windows 8.1 64bit

 개발툴 : Android Studio 1.5

 SDK Version : Min 21, Max 23

 작성날짜 : 2016-06-22




참고 : IT Reading - 안드로이드에서 xml 데이터 객체로 바꾸기


기상청 RSS 정보 파일을 사용하기 위해 Xml 파서를 구현하고 정리를 합니다.


기상청 RSS 정보 파일은 Xml로 되어 있으며, 안드로이드에서 사용하기 위해선 Xml 파서를 구현해야합니다.


xml을 다운받아 파일로 저장한 후 파서에서 파일을 읽고 파싱하는 구조로 구현하였습니다.



아래 url은 부여군 부여읍 rss날씨 를 받을 수 있는 url

다른 지역은 다음 페이지에서 링크를 얻을 수 있습니다.



기상청 RSS Xml 파일

일단 data 태그가 여럿있지만... 블로깅을 위해 한개만 올렸습니다.


<rss version="2.0">

<channel>

<title>기상청 동네예보 웹서비스 - 충청남도 부여군 부여읍 도표예보</title>

<link>http://www.kma.go.kr/weather/main.jsp</link>

<description>동네예보 웹서비스</description>

<language>ko</language>

<generator>동네예보</generator>

<pubDate>2016년 06월 22일 (수)요일 11:00</pubDate>

<item>

<author>기상청</author>

<category>충청남도 부여군 부여읍</category>

<title>동네예보(도표) : 충청남도 부여군 부여읍 [X=59,Y=99]</title>

<link>

http://www.kma.go.kr/weather/forecast/timeseries.jsp?searchType=INTEREST&dongCode=4476025000

</link>

<guid>

http://www.kma.go.kr/weather/forecast/timeseries.jsp?searchType=INTEREST&dongCode=4476025000

</guid>

<description>

<header>

<tm>201606221100</tm>

<ts>3</ts>

<x>59</x>

<y>99</y>

</header>

<body>

<data seq="0">

<hour>15</hour>

<day>0</day>

<temp>29.0</temp>

<tmx>30.0</tmx>

<tmn>-999.0</tmn>

<sky>4</sky>

<pty>1</pty>

<wfKor>비</wfKor>

<wfEn>Rain</wfEn>

<pop>60</pop>

<r12>0.0</r12>

<s12>0.0</s12>

<ws>2.0</ws>

<wd>2</wd>

<wdKor>동</wdKor>

<wdEn>E</wdEn>

<reh>60</reh>

<r06>1.0</r06>

<s06>0.0</s06>

</data>

</body>

</description>

</item>

</channel>

</rss> 



WeatherData.java
parser에서 저장할 데이터 클래스

public class WeatherData {
private double current_temp;
private double high_temp;
private double low_temp;
private String weather_code;
private String weather_desc;

public WeatherData(){
this.setCurrent_temp(-999.0);
this.setHigh_temp(-999.0);
this.setLow_temp(-999.0);
this.setWeather_code(null);
this.setWeather_desc(null);
}

public WeatherData(double current_temp, double high_temp, double low_temp, String weather_code, String weather_desc){
this.setCurrent_temp(current_temp);
this.setHigh_temp(high_temp);
this.setLow_temp(low_temp);
this.setWeather_code(weather_code);
this.setWeather_desc(weather_desc);
}

public double getCurrent_temp() {
return current_temp;
}

public void setCurrent_temp(double current_temp) {
this.current_temp = current_temp;
}

public double getHigh_temp() {
return high_temp;
}

public void setHigh_temp(double high_temp) {
this.high_temp = high_temp;
}

public double getLow_temp() {
return low_temp;
}

public void setLow_temp(double low_temp) {
this.low_temp = low_temp;
}

public String getWeather_code() {
return weather_code;
}

public void setWeather_code(String weather_code) {
this.weather_code = weather_code;
}

public String getWeather_desc() {
return weather_desc;
}

public void setWeather_desc(String weather_desc) {
this.weather_desc = weather_desc;
}
}




WeatherParser.java

저장된 xml 파일을 파싱하기 위한 클래스



public class WeatherParser {

    private static final String TAG "WeatherParser";

    public static 
ArrayList<WeatherData> getDatafromFile( String path )    {
        File xmlFile = 
new File(path);

        if
( !xmlFile.exists() ){
            Log.d(
TAG"!xmlFile.exists()");
            return null;
        
}
        Log.d(
TAG"xml data exist");

        try
{
            FileInputStream fis = 
new FileInputStream(xmlFile);
            return 
parse(fis);

        
}catch(Exception e)
        {
            Log.d(
TAG"error parsing");

            
StringWriter sw = new StringWriter();
            
e.printStackTrace( new PrintWriter(sw));
            
String exceptionAsString = sw.toString();

            
Log.e(TAGexceptionAsString);

            return null;
        
}
    }

    
static ArrayList<WeatherData> parse( InputStream in )

          throws XmlPullParserException, IOException
    {
        ArrayList<WeatherData> m_data =
new ArrayList<>();
        try
{
            XmlPullParser parser = Xml.newPullParser()
;
           
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
            
parser.setInput(in, null);
            if
(parser.getEventType() != XmlPullParser.END_TAG){
                parser.nextTag()
;
           
}
           
m_data = readFeed(parser);

       
}finally{
            in.close()
;
       
}
       
return m_data;
   
}


   
static private ArrayList<WeatherData> readFeed( XmlPullParser parser)

          throws XmlPullParserException, IOException
    {
        ArrayList<WeatherData> entries =
new ArrayList<>();
       
parser.require(XmlPullParser.START_TAG, null, "rss");
       
Log.d(TAG, "TAG Name : " + parser.getName());
       
//parser.require(XmlPullParser.START_TAG, null, "channel");
       
boolean done = false;
        int
eventType = parser.getEventType();

        double
current_temp = 0.0;
        double
high_temp = 0.0;
        double
low_temp = 0.0;
       
String weather_code = null;
        
String weather_desc = null;

        while
(eventType != XmlPullParser.END_DOCUMENT && !done){
            String name =
null;
            switch
(eventType){
               
case XmlPullParser.START_DOCUMENT:
                   
// 스트림의 시작입니다. 리스트를 생성합니다.
                   
break;
                case
XmlPullParser.START_TAG:
                   
// 태그를 식별한 뒤 태그에 맞는 작업을 수행합니다.
                   
name = parser.getName();
                    if
(name.equals("temp")) current_temp = readCurrentTemp(parser);
                    else if
(name.equals("tmx")) high_temp = readHighTemp(parser);
                    else if
(name.equals("tmn")) low_temp = readLowTemp(parser);
                    else if
(name.equals("wfKor")) weather_code = readWeatherCode(parser);
                    break;
                case
XmlPullParser.END_TAG:
                   
// 태그의 마지막을 읽었습니다. ITEM을 처리하는 중이면 리스트에 Message를 추가합니다.
                   
name = parser.getName();
                    if
(parser.getName().equals("data")){
                        entries.add(
new WeatherData(current_temp, high_temp, low_temp, weather_code, weather_desc));
                   
}
                   
break;
           
}
            eventType = parser.next()
;
       
}
       
return entries;

    } 



XmlDownloader.java

기상청 rss 정보 파일을 다운로드하는 클래스

public class XmlDownloader extends AsyncTask<String, Void, Void> {

private static final String TAG = "xmlDownLoader";

String appPath;
AysnkTaskSynkListener listener = null;

public XmlDownloader(Context context) {
appPath = context.getApplicationContext().getFilesDir().getAbsolutePath();
}

@Override
protected Void doInBackground(String... params) {
String url = params[0];
String table_name = params[1];
Download(url, table_name);

return null;
}

protected void onPreExecute()
{

}

protected void onPostExecute( Void result )
{
if( listener != null ) listener.onPostExcute();
}

void Download(String urlAddr, String dbTableName)
{
URL url = null;
try {

url = new URL( urlAddr );

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

urlConnection.setRequestMethod("GET");

urlConnection.setDoOutput(true);
urlConnection.connect();

File file = new File(appPath + "/" + dbTableName + ".xml");
if( file.exists() )
{
file.delete();
}

file.createNewFile();

FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = urlConnection.getInputStream();

int totalSize = urlConnection.getContentLength();

int downloadedSize = 0;

byte[] buffer = new byte[1024];
int bufferLength = 0;

while((bufferLength = inputStream.read(buffer)) > 0 )
{
fileOutput.write(buffer, 0, bufferLength);

downloadedSize += bufferLength;
int progress = (int)(downloadedSize * 100 / totalSize);
}
fileOutput.close();
}catch(Exception e)
{
Log.d(TAG, "fail to download / execption : " + e.getMessage());
}
}


public void SetOnPostExcuteListenrer( AysnkTaskSynkListener _listener )
{
listener = _listener;
}

public interface AysnkTaskSynkListener
{
public void onPostExcute();
}

}


MainActivity.java

XmlDownloader 와 WeatherParser를 사용하는 메인 클래스 안에서 사용하는 부분입니다.

private void Init_weather() {
Log.d(TAG, "Init_weather");
tv_currentTemp = (TextView)findViewById(R.id.main_weather_temperature);
tv_higlowTemp = (TextView)findViewById(R.id.main_weather_highlowtemp);
tv_weatherDesc = (TextView)findViewById(R.id.main_weather_desc);
iv_weather = (ImageView)findViewById(R.id.iv_weather);

xmlDownloader = new XmlDownloader(this);
xmlDownloader.SetOnPostExcuteListenrer(this);
xmlDownloader.execute("http://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=4476025000", "weatherdata");
}

private String getWeatherDesc(String weather_code){
String s = " ";
switch (weather_code) {
case "맑음": s = getResources().getString(R.string.mainactivity_weather_clear); break;
case "구름 조금": s = getResources().getString(R.string.mainactivity_weather_partlycloude); break;
case "구름 많음": s = getResources().getString(R.string.mainactivity_weather_mostlycloudy); break;
case "흐림": s = getResources().getString(R.string.mainactivity_weather_cloudy); break;
case "비": s = getResources().getString(R.string.mainactivity_weather_rain); break;
case "눈/비": s = getResources().getString(R.string.mainactivity_weather_snowrain); break;
case "눈": s = getResources().getString(R.string.mainactivity_weather_snow); break;
default: s = getResources().getString(R.string.mainactivity_weather_none); break;
}
return s;
}

private Drawable getWeatherIconId(String weather_code){
Drawable weather_icon_id;
switch (weather_code) {
case "맑음": weather_icon_id = getResources().getDrawable(R.drawable.weather_icon01); break;
case "구름 조금": weather_icon_id = getResources().getDrawable(R.drawable.weather_icon02); break;
case "구름 많음": weather_icon_id = getResources().getDrawable(R.drawable.weather_icon03); break;
case "흐림": weather_icon_id = getResources().getDrawable(R.drawable.weather_icon04); break;
case "비": weather_icon_id = getResources().getDrawable(R.drawable.weather_icon05); break;
case "눈/비": weather_icon_id = getResources().getDrawable(R.drawable.weather_icon06); break;
case "눈": weather_icon_id = getResources().getDrawable(R.drawable.weather_icon07); break;
default: weather_icon_id = getResources().getDrawable(R.drawable.weather_icon08); break;
}
return weather_icon_id;
}

@Override
public void onPostExcute() {
String appPath = this.getApplicationContext().getFilesDir().getAbsolutePath();
ArrayList<WeatherData> weather_data = WeatherParser.getDatafromFile(appPath + "/weatherdata.xml");

if(weather_data != null){
Log.d(TAG, "weather_data != null");
assert tv_currentTemp != null;
String cur_temp = weather_data.get(0).getCurrent_temp() + "";
tv_currentTemp.setText(cur_temp);

assert tv_higlowTemp != null;
double high_temp_d = weather_data.get(0).getHigh_temp();
String high_temp;
if(high_temp_d == -999.0) high_temp = "-";
else high_temp = high_temp_d + "";

double low_temp_d = weather_data.get(0).getLow_temp();
String low_temp;
if(low_temp_d == -999.0) low_temp = "-";
else low_temp = low_temp_d + "";

String temp = high_temp + "/" + low_temp;
tv_higlowTemp.setText(temp);

assert tv_weatherDesc != null;
temp = getWeatherDesc(weather_data.get(0).getWeather_code());
tv_weatherDesc.setText(temp);

assert iv_weather != null;
iv_weather.setImageDrawable(getWeatherIconId(temp));
}

}







posted by Kanais
2016. 6. 21. 16:01 ETC

운영체제 : Windows 8.1 64bit

Chrome Version51.0.2704.103 m

작성날짜 : 2016-06-21


출처 : Github Gist - Downloads all activites from Runtastic



Runtastic 앱의 활동 데이터들을 Strava로 옮기고 싶어서 구글링을 하다가 좋은 정보를 겟!!


먼저 Runtastic 홈페이지에 들어갑니다.


www.runtastic.com


그리고 프로필에서 활동을 선택!


F12를 눌러서 개발자툴을 활성화 시킵니다. (크롬만 가능할 꺼에요)


그리고 Console 창에다가 아래 태그를 복사 붙여넣기를 합니다.


$('body').html('');
$.each(index_data,function(i, value)
{
    var id = value[0],
        url = 'https://' + app_config.domain+user.run_sessions_path+value[0] + '.gpx',
        filename = 'RUNTASTIC-' + value[1] + '-' + value[0] + '.gpx';

    $.ajax({
        url: 'https://' + app_config.domain + user.run_sessions_path + id + '.gpx',
        success: function(data, textStatus, jqXHR)
        {
            if(textStatus == 'success')
            {
                $('<a/>', {
                    'href' : 'data:text/plain;charset=utf-8,' + encodeURIComponent(jqXHR.responseText),
                    'download' : filename,
                    'id' : id
                }).html(filename)
                .before(i + '. Downloaded: ')
                .after('<br/>')
                .prependTo('body');

                $('#' + id)[0].click();
            }
            else
            {
                console.log(textStatus);
            }
        },
        dataType: 'xml',
        beforeSend: function(xhr){
            xhr.setRequestHeader('X-Requested-With', ' ');
        },
    });
});



그리고 엔터!!!!


전부 다운로드하기를 눌러주면 끗!


자 이제 Strava로 업로드를 해봅시다 ㅎㅎㅎㅎㅎㅎ

'ETC' 카테고리의 다른 글

전파 인증 방법  (0) 2015.01.23
posted by Kanais
2016. 6. 14. 14:46 Programming/Android


운영체제 : Windows 8.1 64bit

개발툴 : Android Studio 1.5

SDK Version : Min 21, Max 23

작성날짜 : 2016-06-14



참고 : Daum Developers - URL스키마 안내



앱에서 다음지도가 설치되어 있다면, 다음지도를 실행하고 설치되어있지 않다면 설치유도를 하여 구글플레이에 다음지도 다운로드페이지로 연결하는 부분임.


DaumMapSchemeURL.java

public abstract class DaumMapSchemeURL {
public static final String DAUMMAP_PACKAGE_NAME = "net.daum.android.map";

public static final String DAUMMAP_DOWNLOAD_PAGE =

"https://play.google.com/store/apps/details?id=net.daum.android.map";

private Context mContext;
private Intent mIntent;

public DaumMapSchemeURL(Context context, Intent intent){
this.mContext = context;
this.mIntent = intent;
}

/**
* myp scheme을 처리할 수 있는 어플리케이션이 존재하는지 검사
* @return 사용가능할 경우 true
*/
public boolean canOpenDaummapURL() {
PackageManager pm =
mContext.getPackageManager();
List infos = pm.queryIntentActivities(mIntent, PackageManager.MATCH_DEFAULT_ONLY);

return infos != null && infos.size() > 0;
}

/**
* 다음맵 설치 여부 검사
* @return 설치되어 있을 경우 true
*/
public boolean existDaummapApp() {
PackageManager pm =
mContext.getPackageManager();

try {
return (pm.getPackageInfo(DAUMMAP_PACKAGE_NAME, PackageManager.GET_SIGNATURES) != null);
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}

/**
* 다음맵 다운로드 페이지열기
*/
public static void openDaummapDownloadPage(Context context) {
Intent intent =
new Intent(Intent.ACTION_VIEW).setData(Uri.parse(DAUMMAP_DOWNLOAD_PAGE));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}


DaumMapSchemeURL 사용부분

private Intent onRoute(){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(searchrouteurl));
DaumMapSchemeURL daummap = new DaumMapSchemeURL(context, intent) {
@Override
public boolean canOpenDaummapURL() {
return super.canOpenDaummapURL();
}
};

if(daummap.existDaummapApp()){
return intent;
} else {
DaumMapSchemeURL.openDaummapDownloadPage(context);
}
return null;
}


반환되는 Intent 를 startActivity(intent);    함수를 사용하여 실행해주면 된다.


posted by Kanais