0. 시작하기
먼저 서버를 구축 해주세요! 여기를 참고하시면 됩니다.
1. 안드로이드 앱 만들기
AndroidSendReceiveTest.zip
i) 안드로이드 레이아웃 설계 <LinearLayout 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:orientation="vertical" >
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" >
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="보내는 메시지 : " />
<EditText android:id="@+id/et_message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ems="10" /> </LinearLayout>
<Button android:id="@+id/btn_sendData" style="?android:attr/buttonStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="35dp" android:text="Send" />
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="40dp" android:orientation="horizontal" >
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="받은 메시지 : " />
<TextView android:id="@+id/tv_recvData" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="받은 메시지가 없습니다." /> </LinearLayout>
</LinearLayout>
ii) 소스 파일 만들기 package com.example.androidsendreceivetest;
import java.io.BufferedReader; import java.io.InputStreamReader;
import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject;
import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView;
public class MainActivity extends Activity {
private EditText etMessage; private Button btnSend; private TextView tvRecvData; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); etMessage = (EditText) findViewById(R.id.et_message); btnSend = (Button) findViewById(R.id.btn_sendData); tvRecvData = (TextView) findViewById(R.id.tv_recvData); /* Send 버튼을 눌렀을 때 서버에 데이터를 보내고 받는다 */ btnSend.setOnClickListener(new OnClickListener() { public void onClick(View v) { String sMessage = etMessage.getText().toString(); // 보내는 메시지를 받아옴 String result = SendByHttp(sMessage); // 메시지를 서버에 보냄 String[][] parsedData = jsonParserList(); // 받은 메시지를 json 파싱 tvRecvData.setText(result); // 받은 메시지를 화면에 보여주기 } }); } /** * 서버에 데이터를 보내는 메소드 * @param msg * @return */ private String SendByHttp(String msg) { if(msg == null) msg = ""; // 서버를 설정해주세요!!! String URL = "http://0.0.0.0:8080/MyServer/JSONServer.jsp"; DefaultHttpClient client = new DefaultHttpClient(); try { /* 체크할 id와 pwd값 서버로 전송 */ HttpPost post = new HttpPost(URL+"?msg="+msg);
/* 지연시간 최대 3초 */ HttpParams params = client.getParams(); HttpConnectionParams.setConnectionTimeout(params, 3000); HttpConnectionParams.setSoTimeout(params, 3000);
/* 데이터 보낸 뒤 서버에서 데이터를 받아오는 과정 */ HttpResponse response = client.execute(post); BufferedReader bufreader = new BufferedReader( new InputStreamReader(response.getEntity().getContent(), "utf-8"));
String line = null; String result = "";
while ((line = bufreader.readLine()) != null) { result += line; } return result; } catch (Exception e) { e.printStackTrace(); client.getConnectionManager().shutdown(); // 연결 지연 종료 return ""; } }
/** * 받은 JSON 객체를 파싱하는 메소드 * @param page * @return */ public String[][] jsonParserList(String pRecvServerPage) { Log.i("서버에서 받은 전체 내용 : ", pRecvServerPage); try { JSONObject json = new JSONObject(pRecvServerPage); JSONArray jArr = json.getJSONArray("List");
// 받아온 pRecvServerPage를 분석하는 부분 String[] jsonName = {"msg1", "msg2", "msg3"}; String[][] parseredData = new String[jArr.length()][jsonName.length]; for (int i = 0; i < jArr.length(); i++) { json = jArr.getJSONObject(i); if(json != null) { for(int j = 0; j < jsonName.length; j++) { parseredData[i][j] = json.getString(jsonName[j]); } } } // 분해 된 데이터를 확인하기 위한 부분 for(int i=0; i<parseredData.length; i++){ Log.i("JSON을 분석한 데이터 "+i+" : ", parseredData[i][0]); Log.i("JSON을 분석한 데이터 "+i+" : ", parseredData[i][1]); Log.i("JSON을 분석한 데이터 "+i+" : ", parseredData[i][2]); }
return parseredData; } catch (JSONException e) { e.printStackTrace(); return null; } } }
소스가 워낙 간단해서 해석하는 데 큰 어려움은 없으실 거에요.
주의 깊게 봐두실 부분은 jsonParserList메소드 입니다. 지금 리턴 값이 String[][]인 이유는 받아온 값을 해석하기 위한 부분입니다. 좀 더 나아간 형태로 만들자면, 객체로 받아 List의 형태로 만드셔도 좋습니다.
받아 온 정보가 잘 왔는지 해석하기 위해 로직 아랫 부분에 보시면 로그로 확인하는 부분이 있는 걸 보실 수 있으실 겁니다.
*참고 : 띄어쓰기를 하고 보내면 안됩니다! 제가 그 부분은 생략했는데 띄어쓰기를 하시려면 String 클래스에서 지원하는 replace() 메소드를 이용하시면 됩니다. 즉, " "를 "_"나 "|" 등으로 바꿔주면, 띄어쓰기 부분은 해결 될 겁니다.
iii) AndroidManifest.xml 설정하기 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.androidsendreceivetest" android:versionCode="1" android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.androidsendreceivetest.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
</manifest>
반드시 uses-permission 을 넣어주셔야 인터넷을 사용하 실 수 있습니다. 그리고, targetSdkVersion을 8로 해주셔야 하며, minSdkVersion 즉 최소 버전에는 영향을 받지 않습니다.
2. 서버 파일 만들기
MyServer.zip
i) 라이브러리 넣기 json_simple-1.1.jar
위에 파일을 WEB-INFO 폴더에 'lib' 폴더 아래에 넣어주세요. lib 폴더가 없다면 만드시면 됩니다.
ii) 서버 만들기 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="org.json.simple.*"%>
<% // 데이터를 안드로이드에서 받음 String recvMessage = request.getParameter("msg");
// 초기 선언 JSONObject jsonMain = new JSONObject(); JSONArray jArray = new JSONArray(); JSONObject jObject1 = new JSONObject(); JSONObject jObject2 = new JSONObject(); JSONObject jObject3 = new JSONObject();
// 안드로이드로 보낼 메시지를 만듬 jObject1.put("msg1", recvMessage); jObject2.put("msg2", "메시지2!"); jObject3.put("msg3", "3번째 메시지!"); // 위에서 만든 각각의 객체를 하나의 배열 형태로 만듬 jArray.add(0, jObject1); jArray.add(0, jObject2); jArray.add(0, jObject3);
// 최종적으로 배열을 하나로 묶음 jsonMain.put("List", jArray); // 안드로이드에 보낼 데이터를 출력 out.println(jsonMain.toJSONString()); %>
보시면 데이터를 받자 마자 보내는 게 특징이죠!
만약 DB를 연동해서 사용 하신다면 JSONObject에다가는 DB에서 얻어온 속성 값을 넣고 JSONArray에다가 똑같이 넣고 보내시면 됩니다. 중요한 건 key 값을 서버가 미리 알고 있거나 예약 된 하나의 키를 통해 전체 키를 보내주셔야 한다는 겁니다.
첨부된 파일과는 다르게 예제에선 3개의 jObject를 생성하고 보내는 걸 보고 의아하게 생각하실 텐데 저 부분은 객체를 담을 때 저렇게 담아서 보낸다 라고 이해하시라고 추가한 부분이니 보낼 메시지가 더 늘어날 경우 데이터를 담고, 보내시면 됩니다.
3. 결론
소스를 잘 참고 하시고, 안되시는 부분은 꼭 질문을 주시기 바랍니다. 일단 저는 잘 작동 되는 걸 확인했습니다! 각 소스들은 대제목 바로 아래에 링크를 걸어두었습니다.
수정 사항
2013/08/20 - 하동하동 님이 지적해주신 사항 수정하였습니다. 원래 예제에서는 jObject를 따로 나누어 생성한 묶은 뒤 받았었는데요. 이랬을 때 하나의 Object를 가져와 이름 순서대로 찾으려는 안드로이드 소스와는 달리 Server에서는 이름 별로 객체를 보냈었죠. 즉, {"List":[{"msg3":"3번째 메시지!"},{"msg2":"메시지2!"},{"msg1":"test"}]}와 같이 서버가 보내는데 받는 쪽에서는 하나 의 {}문을 받아서 처리하려고 하니 Warning Error가 생겼었습니다. 그래서 지금 첨부한 파일에는 서버와 안드로이드가 {"List":[{"msg3":"3번째 메시지!","msg1":"test","msg2":"메시지2!"}]} 처럼 하나의 Json Object에 put 된 내용을 해석하게 끔 바꾸었습니다. 다만, 여러개의 객체를 보내는 것을 보여드리기 위해 예제에는 예전 방식이 조금 남겨 두었습니다. 좋은 정보를 알려주신 하동하동님께 감사드립니다^^
2013/08/30 - 안녕하세요^^ 님이 알려주신 서버 부분 에러에 대한 수정사항입니다. 서버에서 받은 자료를 jObject 에 넣어야 하는데 jObject1, 2 3 에 put을 하고 있어서 null 값이 출력 된 것이었습니다. 지금은 수정해서 jObject에 넣는 것으로 변경하였습니다. 알려주셔서 정말 감사드립니다^^
출처: http://dervelJUnit.tistory.com/71 [IT를 보고, 듣고, 사색하고] |