C2DM(Cloud to Device Message)
 - 구글에서 제공하는 안드로이드 푸시 알림 서비스
 - 안드로이드 2.2(Proyo, Level8)부터 지원




원리
 1. App을 실행하면 구글 C2DM 서버로 접속해 Registration ID를 받아온다.
    - Registration ID : Device를 대표하는 고유 ID. 한 번만 발급받아서 사용하면 되므로 DB에 저장하는 것을 추천.
 2. C2DM 서버로 메세지를 푸시하기 위해서는 AuthToken이라는 인증키가 필요하다.
    이 인증키는 인증서와 비슷한 개념으로 생각하면 된다.
 3. 이제 AuthToken과 상대방 Registration ID를 가지고 C2DM 서버로 메세지를 보낸다.(이 부분은 앱서버가 담당)
 4. C2DM에서 해당 Registration ID를 가진 단말을 찾아서 메세지를 푸시해준다.




사용 순서
 1. C2DM 서비스 신청
   아래 사이트에서 C2DM 서비스 신청을 한다.



 2. 등록이 완료되면 아래처럼 메일이 온다.



 3. 아래 사항들은 C2DM을 이용하는데 필요한 요소들에 대한 설명이다.
    (원문 출처 : http://code.google.com/intl/ko-KR/android/c2dm/) 



4. 이제 직접 코드를 작성해보자.
    아래 소스는 '단말기A → 앱서버 → C2DM → 단말기B' 가 아닌
    '단말기A → 단말기A' 예제이다. 물론 아래 소스들을 응용한다면 충분히 위와 같은 로직을 만드는 것이 가능하다.

Talk.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
public class Talk extends Activity {
 
    private static String authToken = null;
 
    EditText msg_text;
    Button msg_send;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        // C2DM 으로부터 Registration ID와 AuthToken을 발급 받는다.
        try {
            requestRegistrationId();
            authToken = getAuthToken();
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        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) {
                // 메세지를 보낸다.
                try {
                    sender(C2dmReceiver.registration_id, authToken,
                            msg_text.getText().toString());
                    Log.v("C2DM", "Send Message : "
                            + msg_text.getText().toString());
                } catch (Exception e) {
                    e.printStackTrace();
                }
 
            }
        });
    }
 
    /** C2DM으로 메세지를 보내는 메소드 */
    public void sender(String registration_id, String authToken, String msg)
            throws Exception {
 
        // collapse_key는 C2DM에서 사용자가 SEND 버튼을 실수로 여러번 눌렀을때
        // 이전 메세지 내용과 비교해서 반복전송되는 것을 막기 위해서 사용된다.
        // 여기서는 반복전송도 허용되게끔 매번 collapse_key를 랜덤함수로 뽑는다.
        String collaspe_key = String.valueOf(Math.random() % 100 + 1);
 
        // 보낼 메세지 조립
        StringBuffer postDataBuilder = new StringBuffer();
 
        postDataBuilder.append("registration_id=" + registration_id);
        postDataBuilder.append("&collapse_key=" + collaspe_key); // 중복방지 필터
        postDataBuilder.append("&delay_while_idle=1");
        postDataBuilder.append("&data.msg=" + URLEncoder.encode(msg, "UTF-8")); // 메세지                                                                          // 내용
 
        // 조립된 메세지를 Byte배열로 인코딩
        byte[] postData = postDataBuilder.toString().getBytes("UTF-8");
 
        // HTTP 프로토콜로 통신한다.
        // 먼저 해당 url 커넥션을 선언하고 연다.
        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"); // POST 방식
        conn.setRequestProperty("Content-Type",
                "application/x-www-form-urlencoded");
        conn.setRequestProperty("Content-Length",
                Integer.toString(postData.length));
        conn.setRequestProperty("Authorization", "GoogleLogin auth="
                + authToken);
 
        // 출력스트림을 생성하여 postData를 기록.
        OutputStream out = conn.getOutputStream();
 
        // 출력(송신)후 출력스트림 종료
        out.write(postData);
        out.close();
 
        // 소켓의 입력스트림을 반환
        conn.getInputStream();
    }
 
    /**
     * Request for RegistrationID to C2DM Activity 시작시 구글 C2DM으로 Registration ID
     * 발급을 요청한다. Registration ID를 발급받기 위해서는 Application ID, Sender ID가 필요.
     * Registration ID는 Device를 대표하는 ID로써 한번만 받아서 저장하면 되기 때문에 매번 실행시 체크.
     */
    public void requestRegistrationId() throws Exception{
 
        SharedPreferences shrdPref = PreferenceManager
                .getDefaultSharedPreferences(this);
        String registration_id = shrdPref.getString("registration_id", null);
        shrdPref = null;
 
        if (registration_id == null) {
            Intent registrationIntent = new Intent(
                    "com.google.android.c2dm.intent.REGISTER");
 
            // Application ID(Package Name)
            registrationIntent.putExtra("app",
                    PendingIntent.getBroadcast(this, 0, new Intent(), 0));
 
            // Developer ID
            registrationIntent.putExtra("sender", "개발자 Email");
 
            // Start request.
            startService(registrationIntent);
        } else {
            C2dmReceiver.registration_id = registration_id;
            Log.v("C2DM", "Registration ID is Exist!");
            Log.v("C2DM", "Registration ID : " + C2dmReceiver.registration_id);
        }
    }
     
    /**
     * C2DM을 이용하기 위해서는 보안상 authToken(인증키)이 필요하다.
     * authToken도 역시 한 번만 받아놓고 저장한다음 쓰면 된다.
     */
    public String getAuthToken() throws Exception {
 
        SharedPreferences shrdPref = PreferenceManager
                .getDefaultSharedPreferences(this);
        String authToken = shrdPref.getString("authToken", null);
 
        Log.v("C2DM", "AuthToken : " + authToken);
 
        if (authToken == null) {
            StringBuffer postDataBuilder = new StringBuffer();
 
            postDataBuilder.append("accountType=HOSTED_OR_GOOGLE");
            postDataBuilder.append("&Email=개발자 Email");
            postDataBuilder.append("&Passwd=비밀번호");
            postDataBuilder.append("&service=ac2dm");
            postDataBuilder.append("&source=앱의 정보(아무거나 적어도됨)");
 
            byte[] postData = postDataBuilder.toString().getBytes("UTF-8");
 
            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();
 
            Log.v("C2DM", sIdLine);
            Log.v("C2DM", lsIdLine);
            Log.v("C2DM", authLine);
 
            authToken = authLine.substring(5, authLine.length());
 
            SharedPreferences.Editor editor = shrdPref.edit();
            editor.putString("authToken", authToken);
            editor.commit();
        }
 
        shrdPref = null;
        return authToken;
    }
}


C2dmReceiver.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
public class C2dmReceiver extends BroadcastReceiver {
 
    static String registration_id = null;
    static String c2dm_msg = "";
     
    @Override
    public void onReceive(Context context, Intent intent) {
        // 리시버로 받은 데이터가 Registration ID이면
        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.getStringExtra("msg");
 
            // 출력
            Log.v("C2DM", "C2DM Message : " + c2dm_msg);
            Toast toast = Toast.makeText(context, c2dm_msg, Toast.LENGTH_SHORT);
            toast.setGravity(Gravity.TOP | Gravity.CENTER, 0, 150);
            toast.show();
        }
    }
 
    public void handleRegistration(Context context, Intent intent) {
 
        registration_id = intent.getStringExtra("registration_id");
 
        Log.v("C2DM", "Get the Registration ID From C2DM");
        Log.v("C2DM", "Registration ID : " + registration_id);
 
        // 받은 메세지가 error일 경우
        if (intent.getStringExtra("error") != null) {
            Log.v("C2DM", "C2DM REGISTRATION : Registration failed,"
                    + "should try again later");
        }
        // 받은 메세지가 unregistered일 경우
        else if (intent.getStringExtra("unregistered") != null) {
            Log.v("C2DM", "C2DM REGISTRATION : unregistration done, "
                    + "new messages from the authorized "
                    + "sender will be rejected");
        }
        // 받은 메세지가 Registration ID일 경우
        else if (registration_id != null) {
            Log.v("C2DM", "Registration ID complete!");
 
            // Registration ID 저장
            SharedPreferences shrdPref = PreferenceManager
                    .getDefaultSharedPreferences(context);
 
            SharedPreferences.Editor editor = shrdPref.edit();
            editor.putString("registration_id", registration_id);
            editor.commit();
        }
    }
}


main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#ffffff" android:gravity="center_vertical|center">
    <EditText
        android:id="@+id/msg_text"
        android:layout_width="240dip"
        android:layout_height="wrap_content"/>
    <Button
        android:id="@+id/msg_send"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="보내기 "/>
</LinearLayout>


AndroidManifest.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
<?xml version="1.0" encoding="utf-8"?>
      package="앱의 패키지네임"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="8" />
 
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".TalkActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!-- Only C2DM servers can send messages for the app.
            If permission is not set - any other app can generate it -->
        <receiver android:name=".C2dmReceiver"
                  android:permission="com.google.android.c2dm.permission.SEND" >
             <!-- Receive the actual message -->
            <intent-filter >
                <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
                <category android:name="앱의 패키지네임"/>
            </intent-filter>
            <!-- Receive the registration id -->
            <intent-filter >
                <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
                <category android:name="앱의 패키지네임"/>
            </intent-filter>
        </receiver>
    </application>
 
    <!-- Only this application can receive the messages and
        registration result -->
    <permission android:name="앱의 패키지네임.permission.C2D_MESSAGE"
                android:protectionLevel="signature" />
    <uses-permission android:name="앱의 패키지네임.permission.C2D_MESSAGE"/>
     
    <!-- This app has permission to register and receive message -->
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
     
    <!-- Send the registration id to the server -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.USE_CREDENTIALS" />
</manifest>



5. 제대로 받은 키 값들은 아래와 같이 나온다.



6. 메세지 전송 확인



출처 - http://warmz.tistory.com/570


===================================================================================


최근에 알게 되었는데.. 구글에서도 애플의 푸쉬노티피케이션과 같은 서비스를 사용할 수 있게 되었다.
아직은 랩에서 활용되고 있는 것 같다. 일명. C2DM 이며, 안드로이드 버전 2.2에서 사용이 가능하다고 한다.

이것과 관련된 일부 기사를 링크한다.

[번역]안드로이드 C2DM 을 이용한 Chrome to Phone 에 관하여
[번역] 안드로이드 Android Cloud to Device Messaging(C2DM)

관련 기사와 정보를 토대로 가입을 시도해 보았다.
서비스 가입을 위한 사이트는 http://code.google.com/intl/ko-KR/android/c2dm/signup.html 이다.
C2DM 가입 화면
가입을 시도해 보았다.
정보들을 입력하는 과정에서 일 최대 메시지 수, 피크시의 메시지 수와 함께 제한되는 것으로 보내는 쪽의 총 메시지 수와 개별 장비로 전송되는 메시지 수를 검토해서 구글에서 제한 할 수도 있다는 문구가 보인다.

하지만, 가입을 절차를 완료하지 못했다. 아무래도 아직 완성도 있게 만들어 지지는 않은듯 한다.
일부 사용자 중에서는 6월부터 개발해서 테스트가 잘 되었으나 최근들어 서비스가 되지 않는다는 기사도 본적이 있다.
전체 스마트폰의 점유율 1위를 달리는 안드로이드의 푸쉬 서비스 환경에 기대를 해보지만 아직은 접근하기가 쉽지 않은것 같다.

최근 발표된 윈도우폰7에 이어 안드로이드까지 정식 서비스가 된다면 역시 실시간 메시지 전달 플랫폼은 더욱 부각이 될 것이다.


출처 - http://jongryong.wordpress.com/2010/10/29/%EA%B5%AC%EA%B8%80%EC%9D%98-%ED%91%B8%EC%89%AC-%EB%85%B8%ED%8B%B0%ED%94%BC%EC%BC%80%EC%9D%B4%EC%85%98-%EC%84%9C%EB%B9%84%EC%8A%A4-c2dm/


Android Cloud to Device Messaging
[이 포스트는 이 기능을 구현하는데 기여한 Wei Huang 에 의해 작성되었습니다. — Tim Bray]


  새롭게 발표된 안드로이드 2.2 에서, 우리는 Android Cloud to Device Messaging (C2DM) 서비스를 추가하였습니다. 이 서비스는 개발자들이 서버와 모바일 어플리케이션간에 데이타를 쉽게 싱크할 수 있도록, 서버쪽 에서에서 안드로이드 폰 상의 어플리케이션으로 데이타를 손쉽게 전달할 수 있도록 도와줍니다.

 유용한 휴대폰 어플리케이션들은 대부분 사용자가 인터넷과 연결되도록 유지합니다. 이를 위해 전통적으로 많은 어플리케이션들은 주기적으로 데이터를 가져오기 위해 폴링 방식을 사용합니다. 예를들어 POP 이메일 클라이언트의 경우 15분 마다 이메일 서버와 연결되어 새로운 이메일을 가져오도록 구현될 수 있습니다. 이러한 폴링 방식은 비교적 구현하기가 용이하고, 대부분의 경우 잘 작동합니다. 하지만, 어떤한 주기로 폴링 작업을 수행할지 결정하는 것은 조금 애매한 구석이 있습니다. 폴링을 너무 자주하게 되면, 새로운 데이타가 없는데도 불구하고 불피요한 작업이 수행되며 서버와 네트워크에 부하를 줄 수 있습니다. 너무 드물게 폴링을 수행하면 어플리케이션이 갖고 있는 데이터가 전혀 갱신되지 않는 것 처럼 느껴질지도 모릅니다. 특히나 모바일 디바이스에서 효율적으로 폴링 작업을 수행하는 것은 중요한 문제입니다. 왜냐하면 폴링 작업은 귀중한 네트워크 밴드위스와 베터리를 소모시키기 때문입니다.

 폴링 방식을 사용하는 대신, 비동기적으로 클라이언트에 메세지를 푸쉬해주는 서버를 갖추는 것은 어플리케이션이 효율적으로 새로운 데이터를 전달 받을 수 있는 훨씬 좋은 선택이 될 수 있습니다. 하지만 훌륭한 푸쉬 솔루션을 구현하는 것은 어려운 일이며, 서버측과 특정한 연결을 유지하고 있어야 하는 오버헤드가 발생합니다. 특히 안드로이드폰과 같은 모바일 디바이스에서 이를 구현하는데는 네트워크 상태(고르지 못한 네트워크 커버리지, 무선망 상황이 좋지 않아 커넥션을 시도해도 타임아웃에 걸리고 마는 좀비 커넥션등) 에관한 고려가 필요하기 때문에, 교묘한 기술이 필요합니다. 

 G-메일, 주소록, 캘린더와 같은 안드로이드용 구글 어플리케이션은 데이터를 항상 최신으로 유지하기 위해 이미 푸시 방식을 사용하고 있습니다. 안드로이드 2.2 부터 C2DM 를 사용하면 서드파티 개발자들도 구글 어플리케이션과 동일한 서비스를 사용할 수 있습니다.

C2DM 에 대해서 몇 가지 기본적으로 알아야 하는 사항이 있습니다. 
  • 안드로이드 2.2 버전이 필요합니다. 
  • C2DM 은 '구글 서비스'를 사용합니다. 이 서비스는 안드로이드 마켓을 사용하는 모든 디바이스에 존재합니다.
  • C2DM 은 '구글 서비스' 를 위해 이미 존재하는 커넥션을 사용합니다.
  • C2DM 은 안드로이드 폰 상에서 사용자가 구글 계정으로 로그인 해야 사용이 가능합니다.
  • C2DM은 서드파티 서버가 간단한 메세지를 자신들의 어플리케이션으로 전달하는 것을 허용합니다.
  • C2DM 서비스는 대량의 컨텐츠를 푸쉬하도록 설계되지 않았습니다. 대신 특정 어플리케이션에게 새로운 데이타가 있음을 '쿡' 하고 알려 주고, 어플리케이션이 해당 서버에 접속해서 데이타를 다운로드 받을 수 있도록 하는데 사용되어야 합니다. 
  • 어플리케이션은 메세지를 받기 위해 작동중일 필요가 없습니다. 시스템은 전달해야할 데이타가 도착하는 경우에, 브로드캐스트 인텐트를 이용해 해당 어플리케이션을 깨울 것 입니다. 따라서, 어플리케이션은 적절하게 브로드캐스트 리시버와 Permission 을 설정해야 합니다.
  • 데이타 메세지를 전달 받기 위해 사용자 인터페이스가 필요하지는 않습니다. 물론 어플리케이션이 원한다면 알림창에 노티피케이션을 날릴 수도 있을 것 입니다.

C2DM API 를 사용하는 것은 쉽습니다. C2DM 은 아래와 같이 작동합니다.
  • C2DM 을 사용하기 위해 디바이스 상의 어플리케이션은 우선 구글에 등록해 Registration ID 를 발급 받아야 합니다. 해당 ID 를 자신의 서버에 전달해야 합니다. 
  • 만일 자신의 서버가 푸시하고 싶은 메세지가 있을 경우, 메세지를 HTTP 를 통해 구글의 C2DM 서버에 전달합니다. 
  • C2DM 서버는 메세지를 디바이스에 라우팅 하고, 디바이스는 브로드캐스트 인텐트를 어플리케이션에 전달 할 것 입니다. 
  • 타켓 어플리케이션은 브로드 캐스트 인텐트를 통해 깨어나고 메세지를 처리합니다. 
  • 어플리케이션은 사용자가 더이상 푸시 서비스를 받고싶지 않을 경우 등록을 취소할 수 있습니다. 
 거의 다 되었습니다. 개발자에게 필요한 것은 HTTP를 전달할 수 있는 서버와 Intent API 를 어떻게 사용해야하는지 알고 있는 안드로이드용 어플리케이션 뿐입니다. 아래는 간단한 예제 코드입니다.

// Use the Intent API to get a registration ID
// Registration ID is compartmentalized per app/device
Intent regIntent = new Intent(
        "com.google.android.c2dm.intent.REGISTER");
// Identify your app
regIntent.putExtra("app",
        PendingIntent.getBroadcast(this /* your activity */, 
            0, new Intent(), 0);
// Identify role account server will use to send
regIntent.putExtra("sender", emailOfSender);
// Start the registration process
startService(regIntent);

Registration ID 는 개발자의 어플리케이션으로 com.google.android.c2dm.intent. REGISTRATION 이라는 액션값을 갖는 브로드 캐스 인텐트를 통해 전달되어 집니다. 다음은 Registration ID 를 전달 받기위한 예제 코드 입니다.

// Registration ID received via an Intent
public void onReceive(Context context, Intent intent) {
  String action = intent.getAction();
  if (“com.google.android.c2dm.intent.REGISTRATION”.equals(action)) {
    handleRegistration(context, intent);
  }
}

public void handleRegistration(Context context, Intent intent) {
  String id = intent.getExtra(“registration_id”);
  if ((intent.getExtra(“error”) != null) {
    // Registration failed.  Try again later, with backoff.
  } else if (id != null) {
    // Send the registration ID to the app’s server.
    // Be sure to do this in a separate thread.
  }
}

 서버측을 살펴보면, 개발자의 서버는 C2DM 서버와 통신하기 위해 ClientLogin Auth 토큰을 가져야합니다. 토큰을 이용해서, 서버가 디바이스에 메세지를 푸시하고 싶을 때, 다음과 같은 인증된 HTTP Post 를 통해 메세지를 전달 할 수 있습니다. 
  • Authorization: GoogleLogin auth=<auth token>
  • Registration ID 와 키/벨류 쌍으로 이루어진 데이타, Google C2DM 서버에서 동일한 키값을 갖고 있는 오래된 메세지를 가로채기 위해 사용되는 'Collapse Key' 등몇 가지 옵셔널한 파라매터들을 포함하도록 인코딩된 URL.
 개발자가 C2DM 서비스를 사용하면, 골치아픈 모바일 데이타 커넥션을 직접 처리할 필요가 없으며, 사용자가 인터넷과 연결되어있는지 신경쓸 필요도 없습니다. (Airplane 모드와 같이). C2DM 은 서버 스토어에 메세지들을 보관하고, 디바이스가 온라인 상태로 될 때 해당 메세지를 전달합니다. 기본적으로 개발자는 견고한 푸시서비스를 위해 온갖 복잡하고 어려운 일들을 모두 구글에게 맡길 수 있습니다. 어플리케이션은 구글이 이미 구축하고 검증한 푸시 서비스의 이점을 취하고, 인터넷에 연결되어진 상태로 유지될 수 있습니다. 무엇보다도 좋은 것은 여러분이  배터리 소모에대해 비난을 받지 않아도 됩니다.

어떻게 C2DM 이 가능한 어플리케이션을 만들 수 있는 가에 관한 정보는 Code Lab 에 있으며, 서비스 일반 릴리즈가 다가올 수록 보다 다양한 정보가 공개될 것 입니다. 


출처 - http://nuninaya.tistory.com/574







Posted by linuxism
,