경기버스 도착정보 서비스 API 를 http://www.data.go.kr 사이트에서 받아서 XML 데이터를 JSON 으로 파싱하는 예제를 테스트하고 적어둔다.
신청하면 2년간 사용할 수 있게 되어 있다.
프로젝트 build.gradle
allprojects {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
}
}
앱 build.gradle
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.github.bumptech.glide:glide:3.8.0' // 이미지 라이브러리
implementation 'com.android.support:recyclerview-v7:27.1.0' // ListView 개선 버전
implementation 'com.android.support:cardview-v7:27.1.0'
implementation 'gun0912.ted:tedpermission:2.0.0'
implementation 'com.github.smart-fun:XmlToJson:1.1.1'
implementation 'com.android.volley:volley:1.1.0'
}
라이브러리 최신 정보는 https://github.com/smart-fun/XmlToJson 에서 확인해서 최신버전으로 적는게 좋다.
public class MainActivity extends AppCompatActivity { Context context; public static final String TAG = MainActivity.class.getSimpleName(); public EditText edit; public Button send; TextView status1; // http://www.data.go.kr 에서 로그인 후 API 조회하여 신청 승인받은 key 값 String key = "iLOTMTnmawGIweE3%2F4DFwv98g0F3Vv7iJA%3D%3D"; // 실제 키값이 아님 (변경처리함)
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); context = this.getBaseContext();
initView(); }
private void initView() { status1 = (TextView)findViewById(R.id.result); //파싱된 결과확인! edit = (EditText) findViewById(R.id.message) ; send = (Button)findViewById(R.id.send);
// message send action send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(!edit.getText().toString().isEmpty()){ BusArriveTask(edit.getText().toString()); edit.setText(" "); } } }); }
private void BusArriveTask(String search){ RequestQueue requestQueue = Volley.newRequestQueue(context);
String StationId = null; // 정류소 ID try { StationId = URLEncoder.encode(search,"UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } // 버스 도착정보 목록 조회 String url = "http://openapi.gbis.go.kr/ws/rest/busarrivalservice/station?serviceKey="+key+"&stationId="+StationId+""; Log.d(TAG, "URL:"+url);
StringRequest request= new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse(String response) { XMLtoJSONData(response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) {
} });
requestQueue.add(request); }
private void XMLtoJSONData(String xml){ // https://androidfreetutorial.wordpress.com/2016/11/28/how-to-convert-xml-to-json-for-android/ XmlToJson xmlToJson = new XmlToJson.Builder(xml).build(); // convert to a JSONObject JSONObject jsonObject = xmlToJson.toJson(); Log.d(TAG, "jsonObject:"+jsonObject);
// JSON 에서 배열은 [] 대괄호 사용, Objext 는 {} 중괄호 사용 try { JSONObject response = jsonObject.getJSONObject("response"); JSONObject msgHeader = response.getJSONObject("msgHeader"); String resultCode = msgHeader.optString("resultCode"); Log.d(TAG, "String resultCode :"+resultCode);
if(resultCode.equals("0")){ JSONObject msgBody = response.getJSONObject("msgBody"); Log.d(TAG, "jsonObject msgBody :"+msgBody);
JSONArray array = msgBody.getJSONArray("busArrivalList"); for(int i=0; i < array.length();i++){ JSONObject obj = array.getJSONObject(i); // optString which returns the value mapped by name if it exists String plateNo1 =obj.optString("plateNo1"); // 첫번째 차량 번호 String locationNo1 =obj.optString("locationNo1"); // 첫번째 차량 위치 정보 String plateNo2 =obj.optString("plateNo2"); // 두번째 차량 번호 String locationNo2 =obj.optString("locationNo2"); // 두번째 차량 위치 정보 Log.d(TAG, "jString plateNo1 :"+plateNo1); Log.d(TAG, "jString plateNo2 :"+plateNo2); Log.d(TAG, "jString locationNo1 :"+locationNo1); Log.d(TAG, "jString locationNo2 :"+locationNo2); } } else if(resultCode.equals("1")){ Toast.makeText(context, "시스템 에러가 발생하였습니다", Toast.LENGTH_SHORT).show(); } else if(resultCode.equals("4")){ Toast.makeText(context, "결과가 존재하지 않습니다", Toast.LENGTH_SHORT).show(); } else if(resultCode.equals("8")){ Toast.makeText(context, "요청 제한을 초과하였습니다", Toast.LENGTH_SHORT).show(); } else if(resultCode.equals("23")){ Toast.makeText(context, "버스 도착 정보가 존재하지 않습니다", Toast.LENGTH_SHORT).show(); }
} catch (JSONException e) { e.printStackTrace(); } }
}
|
로그캣에만 찍어보도록 코드를 구현한 상태다.
XML 메시지를 JSON 으로 변환하면 아래와 같이 된다.
중괄호를 JSONObject response = jsonObject.getJSONObject("response"); 로 파싱하고
로그캣을 찍어서 메시지를 확인하면서 범위를 좁혀 나가면 된다.
[] 대괄호가 나오는 부분에서는 JSONArray array = msgBody.getJSONArray("busArrivalList"); 로 파싱하고 for 문을 돌려서 원하는 결과를 추출할 수 있다.
공공데이터 파싱하는데 사용한 샘플 코드를 첨부 (RecyclerView 를 이용하여 화면에 뿌리는 예제로 구현)
BusInfo_sample.zip
제대로 만들어 보려고 한다면
부산버스 어플 소스 https://github.com/kmshack/Busanbus-Android 공개된 것으로 공부하면 많은 도움이 될 거 같다.
관련 기사 : http://www.bloter.net/archives/151935