ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C2DM 사용 하기 (1)
    안드로이드/학습&강좌 2011. 6. 13. 01:51


    이전 강좌에서 c2dm을 사용하기전에 설정해 줘야 할 일들에 대해서 언급했다.

    이 과정을 거치지 않고는 c2dm을 사용할 수 없으니 이전 강좌를 미리 참고해 주기 바란다.

    http://ememomo.tistory.com/entry/C2DM서비스사용을위한준비


    이제 간단한 c2dm 환경을 코드화 하여 나타내려고 한다. 내가 올리기도 미안할 정도로

    이부분에 대해서는 안드로이드 사이드에 리칼님이 상세하게 설명해 노았으니

    이부분을 참고 해도 좋다. 이부분에 대해 똑같은 정도의 설명만 할 것이다. 좀더 진도를 나가는 것은 다음 강의부터 올리도록 하겠다.

    http://www.androidside.com/B46/14705 < 리칼님 강좌 >

    UI적인 측면에서도 하나도 수정을 하지 않고 리칼님이 설정해신 대로 필자도 하나씩 단계별로 진행 하도록 하겠다.

    성공 화면을 먼저 보자면


    간단하다 그전 강좌를 그저 따라 햇을 뿐인데도 손쉽게 성공했으니 다들 여기까지는 잘 셋팅 하리라 믿는다.

    초당 메시지 트래픽수를 최대로 설정햇음에도 불구하고 상당히 늦게 도착하더라..

    C2DM 의 단점을 몇가지 설명하자면

    1. 클라우딩 서비스를 이용하기 때문에 메시지의 누실 가능성이 있다.

    2. 순차적인 응답 ( 도착 ) 을 보장 할 수 없다.

    3. 치명적으로 폰이 응답이 없을경우 (전원off )등 일 경우 재전송이 이루어 지지 않는다. (곧 메시지는 누실된다. )

    4. 파일전송 가능여부.. 이 부분을 구현하려면 서드 파티션 단에서 처리를 해줘야 할 것이다. 내생각엔
    (지원하기는 한다는데 용량자체가 미비하다고 알고 있다.


    이런 이유들 때문에 아직 C2dm 을 이용한 상용화는 잘 이루어 지지 않고 있는 실정이다.

    대신 카카오톡에 비해 장점을 설명하면 안드로이드 기기에 대한 고유 디바이스 정보를 가지고 통신하기 때문에

    계속해서 서버와의 응답을 주고 받을 필요가 없어서 베터리 소모가 덜하다.

    이 부분으로 프로젝트를 진행 하려 하면 충분한 고려가 필요 할 것으로 생각된다.

    소스에 대해서는 그냥 붙여 두도록 하겠다. 자세한 설명 자체는 위의 링크페이지에서 확인 하기 바란다.

    패키지 명과, 개발자 이름 / 패스워드 등은 각자 자기가 등록한 프로젝트 패키지명에 맞게 설정하면 된다.



    IntroActivity.java
    package blog.epong.com;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.net.URLEncoder;
    
    import android.app.Activity;
    import android.app.PendingIntent;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    
    public class IntroActivity extends Activity {
    	EditText msg_text;
    	Button msg_send;
    	private OutputStream out = null;
    
    	@Override
    	public void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.main);
    
    		// C2DM 등록ID 발급
    		Intent registrationIntent = new Intent(
    				"com.google.android.c2dm.intent.REGISTER");
    		registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0,
    				new Intent(), 0)); // 어플리케이션ID
    		registrationIntent.putExtra("sender", "xxxxxx@gmail.com"); // 개발자ID
    		startService(registrationIntent); // 서비스 시작(등록ID발급받기)
    		// 위에서 지정한 "app"와 "sender"은 맘대로 지정하시는게 아니라 구글에서 필요한 변수명들입니다.
    
    		msg_text = (EditText) 	findViewById(R.id.msg_text);
    		msg_send = (Button) 	findViewById(R.id.msg_send);
    
    		msg_send.setOnClickListener(new OnClickListener() {
    			@Override
    			public void onClick(View v) {
    				// TODO Auto-generated method stub
    				try {
    					// 메시지를 보낼때 sender(발급받은 ID, 토큰인증값, 메시지)
    					sender(C2dm_BroadcastReceiver.registration_id,
    							getAuthToken(), msg_text.getText().toString());
    				} catch (Exception e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		});
    	}
    
    	public void sender(String regId, String authToken, String msg)
    			throws Exception {
    		StringBuffer postDataBuilder = new StringBuffer();
    
    		postDataBuilder.append("registration_id=" + regId); // 등록ID
    		postDataBuilder.append("&collapse_key=1");
    		postDataBuilder.append("&delay_while_idle=1");
    		postDataBuilder.append("&data.msg=" + URLEncoder.encode(msg, "UTF-8")); // 태울
    																				// 메시지
    
    		byte[] postData = postDataBuilder.toString().getBytes("UTF8");
    
    		URL url = new URL("https://android.apis.google.com/c2dm/send");
    
    		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    		conn.setDoOutput(true);
    		conn.setUseCaches(false);
    		conn.setRequestMethod("POST");
    		conn.setRequestProperty("Content-Type",	   	"application/x-www-form-urlencoded");
    		conn.setRequestProperty("Content-Length",  	Integer.toString(postData.length));
    		conn.setRequestProperty("Authorization", 	"GoogleLogin auth=" + authToken);
    
    		OutputStream out = conn.getOutputStream();
    		out.write(postData);
    		out.close();
    
    		conn.getInputStream();
    
    	}
    
    	public String getAuthToken() throws Exception {
    		String authtoken = "";
    
    		StringBuffer postDataBuilder = new StringBuffer();
    		postDataBuilder.append("accountType=HOSTED_OR_GOOGLE"); // 똑같이 써주셔야 합니다.
    		postDataBuilder.append("&Email=xxxxxx@gmail.com");     // 개발자 구글 id
    		postDataBuilder.append("&Passwd=xxxxxx"); 		  	// 개발자 구글 비빌번호
    		postDataBuilder.append("&service=ac2dm");
    		postDataBuilder.append("&source=test-1.0");
    
    		byte[] postData = postDataBuilder.toString().getBytes("UTF8");
    
    		URL url = new URL("https://www.google.com/accounts/ClientLogin");
    
    		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    		conn.setDoOutput(true);
    		conn.setUseCaches(false);
    		conn.setRequestMethod("POST");
    		conn.setRequestProperty("Content-Type",	  "application/x-www-form-urlencoded");
    		conn.setRequestProperty("Content-Length", Integer.toString(postData.length));
    
    		OutputStream out = conn.getOutputStream();
    		out.write(postData);
    		out.close();
    
    		BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    
    		String sidLine = br.readLine();
    		String lsidLine = br.readLine();
    		String authLine = br.readLine();
    
    		System.out.println("sidLine----------->>>"  + sidLine);
    		System.out.println("lsidLine----------->>>" + lsidLine);
    		System.out.println("authLine----------->>>" + authLine);
    		System.out.println("AuthKey----------->>>"	+ authLine.substring(5, authLine.length()));
    
    		authtoken = authLine.substring(5, authLine.length());
    
    		return authtoken;
    	}
    }
    
    
    C2dm_BroadcastReceiver.java
    package blog.epong.com;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.util.Log;
    import android.view.Gravity;
    import android.widget.Toast;
    
    public class C2dm_BroadcastReceiver extends BroadcastReceiver {
    
    	static String registration_id = null;
    	static String c2dm_msg = "";
    
    	@Override
    	public void onReceive(Context context, Intent intent) {
    		if (intent.getAction().equals(
    				"com.google.android.c2dm.intent.REGISTRATION")) {
    
    			handleRegistration(context, intent);
    
    		} else if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {
    
    			c2dm_msg = intent.getExtras().getString("msg");
    
    			System.out.println("c2dm_msg======>" + c2dm_msg);
    			Toast toast = Toast.makeText(context, "메시지 도착!\n" + c2dm_msg,
    					Toast.LENGTH_SHORT);
    			toast.setGravity(Gravity.TOP | Gravity.CENTER, 0, 150);
    			toast.show();
    
    		}
    	}
    
    	private void handleRegistration(Context context, Intent intent) {
    
    		registration_id = intent.getStringExtra("registration_id");
    
    		System.out.println("registration_id====>" + registration_id);
    
    		if (intent.getStringExtra("error") != null) {
    
    			Log.v("C2DM_REGISTRATION", ">>>>>"
    					+ "Registration failed, should try again later." + "<<<<<");
    
    		} else if (intent.getStringExtra("unregistered") != null) {
    
    			Log.v("C2DM_REGISTRATION",">>>>>"
    									+ "unregistration done, new messages from the authorized sender will be rejected"
    									+ "<<<<<");
    
    		} else if (registration_id != null) {
    
    			System.out.println("registration_id complete!!");
    		}
    	}
    
    }
    
    마지막으로 main.xml
    
    
    
        
    
        
            
                
                    
                    
                
            
             
    			
    				
    				
    			
    		
    				
    				
    		
        	
        
        
    	    
    	    
    	    
    
    
    이렇게 설정해서 메시지 받는데 성공했다면 이제 C2dm을 이용한 프로젝트를 진행 할 수 있는 여건을 마련했다고 생각하자. 이 강의 최종목표는 여러대의 안드로이드 폰에서의 통신가능 이다. 각각의 개인프로필 저장 / 채팅하기 / 전화걸기 / 알림설정 하기 정도수준의 강의를 이어 나가도록 하겠다. 다음 강의에선 디바이스간 처리를 하기 위한 서드 파티션에 대해서 알아보도록 하자~

    댓글 3

    • 프로필사진

      참.. C2DM 좋은데.. 신뢰성 때문에 상당히 망설여지네요.. 특히 프로요에서 구글톡 사용시 아예 에러뿜어버리니... 진저에서는 수정되었더라구요.. 참 C2DM을 써야할지 말아야할지 일주일째 고민중인 1인입니다..

      2011.07.07 04:38
    • 프로필사진

      단점이 또 있네요.. 앱 배포를 다 했는데 구글 비번을 바꿔야한다면..

      2011.08.23 13:22
      • 프로필사진

        보통의 개인정보 같은 경우는 단말과 같이 안넣고 따로 서버쪽에서 저장해서 데이터를 얻어 오는 형식으로 구성하기때문에 그부분에선 문제가 되지 않습니다. 개인정보를 같이 어플단에 넣어 둘경우는.. 상당히 위험하겠죠 ㅎㅎ

        2011.08.23 15:19 신고
COPYRIGHT 2010 EpoNg. ALL RIGHTS RESERVED.