Google Cloud Messaging
GCM(Google 클라우드 메시징)은 개발자가 서버에서 자신의 Android 애플리케이션으로 데이터를 전송하게 해주는 무료 서비스입니다. 서버에서 가져와야할 새로운 데이터(예: 친구가 업로드한 영화)가 있음을 Android 애플리케이션에 알리는 적은 용량의 메시지이거나, 최대 4KB의 페이로드 데이터를 포함하는 메시지일 수 있습니다. 따라서 메신저와 같은 앱은 메시지를 직접 사용할 수 있습니다.
GCM Android jar file path:
Architecture
Sample_init_gcm.jpg
Client setting
GCM을 사용하기 위한 클라이언트(안드로이드) 설정 방법을 정리한다.
AndroidManifest.xml setting
중요한 점은 "my.project.package"부분을 자신을 프로젝트 패키지명으로 변경해야 한다.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name="my.project.package.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="my.project.package.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<!-- 젤리빈 부터는 category가 없어도 된다. -->
<category android:name="my.project.package" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
...
</application>
참고로 Gradle을 사용할 경우 아래와 같이 설정하면 된다.
dependencies {
compile 'com.google.android.gms:play-services-base:+'
compile 'com.google.android.gms:play-services-gcm:+'
compile 'com.google.android.gms:play-services:+'
compile files('libs/gcm-server.jar')
compile files('libs/gcm.jar')
}
MainActivity.java
첫 번째 시작되는 Activity(MainActivity)의 onCreate()에 아래와 같이 GCM을 등록한다.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ...
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId == null || regId.length() == 0) {
// 정상적으로 등록될 경우 GCMIntentService.onRegistered()로 Event가 Callback된다.
GCMRegistrar.register(this, "85810567300");
}
Log.d(TAG, "GCM Register" + regId);
}
GCMIntentService.java
GCMBaseIntentService
를 상속받는 서비스를 구현해야 한다. AndroidManifest에 등록된 서비스 클래스 명칭과 동일해야 한다. 가급적 GCMIntentService을 고정하여 사용하도록 하자.
public class GCMIntentService extends GCMBaseIntentService {
private static final String TAG = GCMIntentService.class.toString();
private static final String PROJECT_ID = "my-project-id"; // 등록된 프로젝트 ID로 적용한다.
// public 기본 생성자를 무조건 만들어야 한다.
public GCMIntentService() {
this(PROJECT_ID);
}
public GCMIntentService(String project_id) {
super(project_id);
}
/** 에러 발생 */
@Override
protected void onError(Context arg0, String arg1) {
Log.e(TAG, "onError: " + arg1);
}
/** 푸시 메세지 획득. */
@Override
protected void onMessage(Context arg0, Intent arg1) {
Bundle b = arg1.getExtras();
Iterator<String> iterator = b.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
String value = b.get(key).toString();
Log.d(TAG, "onMessage. " + key + " : " + value);
}
}
/** 단말에서 GCM 서비스 등록 했을 때 등록 id를 받는다 */
@Override
protected void onRegistered(Context arg0, String arg1) {
Log.e(TAG, "onRegistered: " + arg1);
}
/** 단말에서 GCM 서비스 등록 해지를 하면 해지된 등록 id를 받는다 */
@Override
protected void onUnregistered(Context arg0, String arg1) {
Log.e(TAG, "onUnregistered: " + arg1);
}
}
Troubleshooting
GCM과 관련된 문제점 및 해결 방법에 대하여 정리한다.
No receivers for action com.google.android.c2dm.intent.REGISTRATION
No receivers for action com.google.android.c2dm.intent.REGISTRATION
에러 메세지가 출력될 경우 receiver
의 intent-filter
에 아래와 같이 action
을 추가하면 된다.
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
GcmBroadcastReceiver Class Not Found Exception
java.lang.ClassNotFoundException: com.google.android.gcm.GcmBroadcastReceiver
에러 메세지가 출력될 경우 android-suppert-v4.jar
를 업데이트하거나 receiver
의 android:name
속성에 Package 전체 경로를 적어놓도록 한다.
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
....
</receiver>
혹시 앱이 죽지 않지만 로그캣에 IntentReceiver com.google.android.gcm.GCMBroadcastReceiver@40233b88 that was originally registered here. Are you missing a call to unregisterReceiver()?
와 같은 에러 로그가 출력된다면 GCM서비스 등록 코드를 자신의 앱 application 클래스의 onCreate()로 옮겨주면 된다.
Cannot resolve symbol GCM
- Cannot resolve symbol gcm (Android Studio 0.8.9)
- Cannot resolve com.google.android.gcm.GCMBaseIntentService; Android studio
정리하면, GCMBaseIntentService는 obsolete되어있다. Android SDK Manager에서 하단의 Obsolete 라디오 버튼을 클릭하면 Extras에 아래 이름의 패키지가 출력된다.
Libraries
See also
Favorite site
- Google Cloud Messaging for Android
- Wikipedia (en) GCM에 대한 설명
- GCM(Google 클라우드 메시징)
- Implementing GCM Client
- Implementing GCM Server
Guide
- Android GCM 활용해서 푸시 메세지 전송기
- 안드로이드 GCM(푸쉬서버) 정리
- Java로 GCM, APNS 사용하기 1
- Android GCM (Google Cloud Message) 오류
- GCM 개발 2편 - Android Application 만들기
Tutorial
- GCM 사용하기 1 (GCM 서비스 신청하기) 2
- GCM 사용하기 2 (단말에 GCM 구현하기) 3
- GCM 사용하기 3 (JSP로 GCM 푸시 서버 만들기) 4
- GCM (2) – 클라이언트 만들기
- Google Cloud Messaging for Android(GCM) 활용하기