user@namudi: ~

Android 서울시 지하철 실시간 도착정보 API 연동

>2023.03.12.
웹사이트나 애플리케이션을 만들다 보면 다른 곳에서 데이터를 가져와야 할 때가 있습니다. 필요한 데이터들은 기업이나 공공기관에서 공개하여 배포하기도 하는데, 대표적인 예가 OP.GG나 FOW.KR 같은 게임 전적검색 웹사이트입니다. 이들 웹사이트는 게임사에서 제공하는 외부 API를 받아와 가공해 사용자에게 서비스를 제공하고 있는데, 국가나 공공기관에서도 사회기반시설의 API를 공개해 활용할 수 있도록 하고 있습니다. 우리가 아는 카카오지하철이나 카카오버스가 대표적인데, 지자체나 공공기관에서 정보를 제공받아 가공해 사용자들에게 서비스를 제공하고 있습니다. 카카오지하철, 카카오버스 앱에서 설정 - 정보 제공처를 확인해 보시면 제공처를 확인하실 수 있습니다.

공공데이터 신청

먼저 공공데이터포털 또는 서울 열린데이터 광장에서 API 사용 신청을 하고 인증키를 발급받아야 합니다. 서울시 지하철 실시간 도착정보 API의 샘플 URL을 확인해 보면 다음과 같은 형식입니다. 서울시에서 제공하는 샘플 URL서울시에서 제공하는 샘플 URL
API 페이지에서 샘플 URL을 확인할 수 있으니 참고해 주세요. 샘플 URL에서 (인증키) 부분을 sample로 바꾸면 내용을 확인하실 수 있습니다. 또 URL에서 xml 부분을 json으로 바꾸면 xml 파일이 아닌 json 파일로 받을 수 있습니다.

Android 구현 (MainActivity.java)

XmlPullParser를 사용하여 XML 데이터를 파싱하는 예제 코드입니다. 네트워크 작업은 메인 스레드에서 할 수 없으므로 별도의 스레드를 생성하여 처리했습니다.
public class MainActivity extends AppCompatActivity {
 
    TextView textView;
    String data;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        textView = findViewById(R.id.textView);
    }
 
    public void mOnClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        data = getXmlData();
 
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                textView.setText(data);
                            }
                        });
                    }
                }).start();
                break;
        }
    }
 
    String getXmlData() {
        StringBuffer buffer = new StringBuffer();
        // 샘플 URL 사용 (실제 사용 시 본인의 인증키로 교체 필요)
        String queryUrl = "http://swopenapi.seoul.go.kr/api/subway/sample/xml/realtimeStationArrival/0/5/서울";
 
        try {
            URL url = new URL(queryUrl);
            InputStream is = url.openStream();
 
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            XmlPullParser xpp = factory.newPullParser();
            xpp.setInput(new InputStreamReader(is, "UTF-8"));
 
            String tag;
 
            xpp.next();
            int eventType = xpp.getEventType();
            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch(eventType) {
                    case XmlPullParser.START_DOCUMENT:
                        buffer.append("파싱 시작...\n\n");
                        break;
 
                    case XmlPullParser.START_TAG:
                        tag = xpp.getName();
 
                        if (tag.equals("subwayId")){
                            buffer.append("지하철호선ID : ");
                            xpp.next();
                            buffer.append(xpp.getText());
                            buffer.append("\n");
                        }
                        else if (tag.equals("trainLineNm")){
                            buffer.append("도착지방면 : ");
                            xpp.next();
                            buffer.append(xpp.getText());
                            buffer.append("\n");
                        }
                        else if (tag.equals("arvlMsg2")){
                            buffer.append("도착메세지 : ");
                            xpp.next();
                            buffer.append(xpp.getText());
                            buffer.append("\n");
                        }
                        // 필요한 태그들을 추가로 처리...
                        break;
 
                    case XmlPullParser.TEXT:
                        break;
                    case XmlPullParser.END_TAG:
                        tag = xpp.getName();
                        if (tag.equals("row")) buffer.append("\n");
                        break;
                }
                eventType = xpp.next();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        buffer.append("파싱 끝\n");
        return buffer.toString();
    }
}

실행 결과

실행 결과실행 결과
위 코드를 실행하고 버튼을 누르면, 서울역(예제 URL 기준)의 실시간 지하철 도착 정보가 텍스트 뷰에 출력됩니다. subwayId, trainLineNm, arvlMsg2 등의 태그를 통해 호선 정보, 방면, 도착 예정 시간 등을 확인할 수 있습니다.