반응형
미니 플젝으로 평소에 만들어보고 싶었던 '부산 버스' 어플을 구현하였다.
API는 공공데이터 포털(data.go.kr)에서 받아왔으며 xml로 파싱하여 값을 받아왔다.
api 파싱과 값 뽑아오는 부분에서는 정말 맨땅에 헤딩이어서 이틀 밤샘 삽질하다가 겨우겨우 해결했다ㅠㅠ
http://movie13.tistory.com/1 << 여기 이 블로그에서 많은 도움을 받았다!!
위의 사이트에서 원하는 api를 검색 후 활용신청하고 end point 와 service key를 받아놓는다. 참고문서도 내려받아서 참고하면된다.
UI부분에 좀 더 투자를 하고 싶었지만 값을 받아내는데 급급해서 사진만 넣고 스크롤뷰에 textview만 넣었다..
<레이아웃>
버스번호와 정류장 번호를 입력하면 해당 정류장에 입력한 버스가 언제 도착하는지를 알려준다.
근데.. 제작 다하고 발표하는 날에 치명적인 오류가 발생하였다..
????? 현재시각 오전 11:13 인데 절대 버스가 없을리가 없는데 왜이렇지 하고 코드분석을 했는데...
알고보니
띠용 ...... 이럴수가....
이 상태가 된지 2주가 넘은거같은데 처리 부탁드립니다...(_ _)
아래는 안드로이드에서 작업한 xml과 java코드이다.
<activity_main.xml>
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/road" android:orientation="vertical" android:weightSum="10" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="언제 도착하지?" android:textColor="#ffffffff" android:textSize="40dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="4" android:orientation="vertical" android:weightSum="5"> <EditText android:id="@+id/busNum" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="2" android:background="@null" android:ems="10" android:hint="버스 번호를 입력해주세요." android:inputType="textPersonName" android:text="" android:textColor="#ffffffff" android:textColorHint="#D5D5D5" /> <EditText android:id="@+id/stationArsno" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="2" android:background="@null" android:ems="10" android:hint="정류장 번호를 입력해주세요." android:inputType="textPersonName" android:text="" android:textColor="#ffffffff" android:textColorHint="#D5D5D5" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="0dp" android:layout_gravity="center" android:layout_weight="1" android:onClick="search" android:text="검색하기" /> </LinearLayout> <ScrollView android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="5" android:background="@color/colorBlack"> <TextView android:id="@+id/showInfo" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:textColor="#ffffffff" android:textSize="20dp" /> </ScrollView> </LinearLayout> | cs |
<MainActivity.java>
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 | package com.example.sh.bus; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.WindowManager; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserFactory; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.regex.Matcher; import java.util.regex.Pattern; public class MainActivity extends AppCompatActivity { private final String TAG = "myTag"; private final String key = "WyP9pjBjktC%2Bea2fFObCERMWEwTJGwwsRMr1YeyFGuqKZSnQwmKcnk1n3ZKf6L8UMGjCSZ4HZDCC%2BSQol89tjQ%3D%3D"; private final String endPoint = "http://61.43.246.153/openapi-data/service/busanBIMS2"; //xml 변수 private EditText xmlBusNum; private EditText xmlStationArsno; private TextView xmlShowInfo; // 파싱을 위한 필드 선언 private URL url; private InputStream is; private XmlPullParserFactory factory; private XmlPullParser xpp; private String tag; private int eventType; // xml의 값 입력 변수 private String busNum; // 버스 번호 private String stationArsno = ""; //출발 정류장 arsNo private StringBuffer buffer; // 데이터 검색 private String busNumId; // 버스 번호 Id private String stationId;// 출발 정류소명 Id private String sStationArriveTime; // 버스의 정류장 도착정보 private String car1; private String min1; private String station1; private String car2; private String min2; private String station2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //상태바 없애기(FullScreen) getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_main); //xml 아이디 얻어오기 getXmlId(); buffer = new StringBuffer(); } //검색하기 onclick버튼 public void search(View view) { //사용자한테 출발정류장, 도착정류장 알아오기. busNum = xmlBusNum.getText().toString(); stationArsno = xmlStationArsno.getText().toString(); car1 = min1 = station1 = car2 = min2 = station2 = null; buffer = null; buffer = new StringBuffer(); xmlShowInfo.setText(""); //입력값 검사 함수 if(exmineData()) { // 입력값 검사 함수에서 true를 return할 경우 값이 잘못된 것.. // 종료.. return; } new Thread(new Runnable() { @Override public void run() { // 검색한 버스 id 얻기 // 오퍼레이션 2 getBusId(busNum); //검색한 정류장 얻기 //오퍼레이션 1 getStationId(stationArsno); //버스가 언제오는지 확인 //오퍼레이션 5 userWant(busNumId, stationId); // UI setText 하는 곳.. runOnUiThread(new Runnable() { @Override public void run() { Log.d(TAG, car1 + " " + min1 + " " + station1); Log.d(TAG, car2 + " " + min2 + " " + station2); if(car1 == null) { buffer.append("도착 정보 없음"); } else { buffer.append("첫번째 차량 도착 정보\n"); buffer.append("차량 번호 : " + car1 + " \n"); buffer.append("남은 시간 : " + min1 + " 분 \n"); buffer.append("남은 구간 : " + station1 + "정거장\n"); } // 두번째 도착 차량은 null이 아닐 경우에만 출력 if(car2 != null) { buffer.append("-------------------------\n"); buffer.append("두번째 차량 도착 정보\n"); buffer.append("차량 번호 : " + car2 + " \n"); buffer.append("남은 시간 : " + min2 + "분 \n"); buffer.append("남은 구간 : " + station2 + "정거장 \n"); } xmlShowInfo.setText(buffer.toString()); } }); } }).start(); } //정류소명을 입력하면 정류장 ID를 돌려줌 /* * 오퍼레이션 1 * 정류소명, 정류소ARS번호를 기준으로 정류소ID, 정류소명, GPS좌표, 정류소구분(일반, 마을)을 * 조회하는 정류소정보 조회 서비스 */ public void getStationId(String station) { String stationUrl = endPoint + "/busStop?arsno=" + station + "&serviceKey=" + key; Log.d(TAG, "정류장명 -> 정류장Id : " + stationUrl); try { setUrlNParser(stationUrl); while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_DOCUMENT: break; case XmlPullParser.START_TAG: tag = xpp.getName(); if (tag.equals("item")) ; //첫번째 검색 결과 else if (tag.equals("bstopId")) { xpp.next(); stationId = xpp.getText(); } else if (tag.equals("bstopArsno")) ; else if (tag.equals("bstopNm")) ; else if (tag.equals("gpsX")) ; else if (tag.equals("gpsY")) ; else if (tag.equals("stoptype")) ; break; case XmlPullParser.TEXT: break; case XmlPullParser.END_TAG: tag = xpp.getName(); if (tag.equals("item")); // 첫번째 검색 결과 종료.. 줄바꿈 break; } //end of switch~case eventType = xpp.next(); } //end of while } catch (Exception e) { e.printStackTrace(); } //return buffer.toString(); //정류장 이름에 해당하는 id를 넘겨줌 } //버스 번호를 입력하면 버스 ID를 돌려줌 /* * 오퍼레이션 2 * 노선ID, 노선번호를 기준으로 버스종류, 회사이름, 출/도착지, 첫/막차시간, 배차간격을 조회하는 노선정보 조회 서비스 */ public void getBusId(String busNum) { String busNumUrl = endPoint + "/busInfo?lineno=" + busNum + "&serviceKey=" + key; Log.d(TAG,"버스번호 -> 버스id : " + busNumUrl); try { setUrlNParser(busNumUrl); while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_DOCUMENT: break; case XmlPullParser.START_TAG: tag = xpp.getName(); if (tag.equals("item")) ; //첫번째 검색 결과 else if (tag.equals("lineId")) { xpp.next(); busNumId = xpp.getText(); } else if (tag.equals("buslinenum")) ; else if (tag.equals("bustype")) ; else if (tag.equals("companyid")) ; else if (tag.equals("endpoint")) ; else if (tag.equals("stoptype")) ; else if (tag.equals("firsttime")) ; else if (tag.equals("endtime")) ; else if (tag.equals("headway")) ; else if (tag.equals("headwayNorm")) ; else if (tag.equals("headwayPeak")) ; else if (tag.equals("headwayHoli")) ; break; case XmlPullParser.TEXT: break; case XmlPullParser.END_TAG: tag = xpp.getName(); if (tag.equals("item")); // 첫번째 검색 결과 종료.. 줄바꿈 break; } //end of switch~case eventType = xpp.next(); } //end of while } catch (Exception e) { e.printStackTrace(); } } /* * 오퍼레이션 5 * 정류소 ID, 노선 ID를 기준으로 실시간 도착정보인 차량번호, 남은 도착시간, 남은 정류장 수 * 저상버스유무를 인접버스 두 대에 대해 조회하는 노선 정류소 도착정보 조회 서비스 */ public void userWant(String busNumId, String stationId) { String dataUrl = endPoint + "/busStopArr?bstopid=" + stationId + "&lineid=" + busNumId + "&serviceKey=" + key; Log.d(TAG, dataUrl); try { setUrlNParser(dataUrl); while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_DOCUMENT: break; case XmlPullParser.START_TAG: tag = xpp.getName(); if (tag.equals("item")) ; //첫번째 검색 결과 else if (tag.equals("carNo1")) { xpp.next(); car1 = xpp.getText(); } else if (tag.equals("min1")) { xpp.next(); min1 = xpp.getText(); } else if (tag.equals("station1")) { xpp.next(); station1 = xpp.getText(); } else if (tag.equals("carNo2")) { xpp.next(); car2 = xpp.getText(); } else if (tag.equals("min2")) { xpp.next(); min2 = xpp.getText(); } else if (tag.equals("station2")) { xpp.next(); station2 = xpp.getText(); }else if (tag.equals("bstopId")) ; else if (tag.equals("nodeNm")) ; else if (tag.equals("companyid")) ; else if (tag.equals("gpsX")) ; else if (tag.equals("gpsY")) ; else if (tag.equals("bustype")) ; else if (tag.equals("lineid")) ; else if (tag.equals("bstopidx")) ; break; case XmlPullParser.TEXT: break; case XmlPullParser.END_TAG: tag = xpp.getName(); if (tag.equals("item")); // 첫번째 검색 결과 종료.. 줄바꿈 break; } //end of switch~case eventType = xpp.next(); } //end of while } catch (Exception e) { e.printStackTrace(); } } // 사용자가 입력한 값을 검사하는 함수 public boolean exmineData() { // 사용자가 하나 이상의 값을 입력하지 않은 경우 if (busNum.equals("") || stationArsno.equals("")) { Toast.makeText(this, "값을 입력해주세요!", Toast.LENGTH_SHORT).show(); return true; } //String[] arr = new String[] {busNum, stationArsno}; String regExp = "([0-9])"; // 입력값은 반드시 숫자여야하므로 정규 표현식으로 설정 Pattern pattern_symbol = Pattern.compile(regExp); //버스 번호 유효성 검사 Matcher matcher_busNum = pattern_symbol.matcher(busNum); // 입력값이 유효하다면 true return if(matcher_busNum.find() == false) { Toast.makeText(this, "버스 번호를 다시 입력해주세요!", Toast.LENGTH_SHORT).show(); return true; } //정류장 번호 유효성 검사 Matcher matcher_stationArsno = pattern_symbol.matcher(stationArsno); // 입력값이 유효하다면 true return if(matcher_stationArsno.find() == false) { Toast.makeText(this, "정류장 번호를 다시 입력해주세요!", Toast.LENGTH_SHORT).show(); return true; } return false; //모든 값이 정상 } // Url, XmlPullParser 객체 생성 및 초기화 public void setUrlNParser(String quary) { try { url = new URL(quary); //문자열로 된 요청 url을 URL객체로 생성 is = url.openStream(); factory = XmlPullParserFactory.newInstance(); xpp = factory.newPullParser(); xpp.setInput(new InputStreamReader(is, "UTF-8")); //inputStream으로부터 xml입력받기 xpp.next(); eventType = xpp.getEventType(); } catch (Exception e) { } } // UI ID 얻는 함수 public void getXmlId() { xmlBusNum = findViewById(R.id.busNum); xmlStationArsno = findViewById(R.id.stationArsno); xmlShowInfo = findViewById(R.id.showInfo); } } | cs |
반응형
'Android' 카테고리의 다른 글
[Android] 전체화면 전환 (0) | 2018.08.17 |
---|---|
[Android] 피아노 어플만들기 (0) | 2018.08.17 |