Google Cloud Messaging
lastmod 2018-08-17created 2014-05-0129 edits
GCM (Google Cloud Messaging) is a free service that lets developers send data from their servers to their Android applications. It can be a small message telling the Android application that there is new data to fetch from the server (e.g. a movie uploaded by a friend), or a message containing up to 4KB of payload data. Apps such as messengers can therefore use the message directly.
GCM Android jar file path:
Architecture
Sample_init_gcm.jpg
Client setting
Notes on how to set up the client (Android) to use GCM.
AndroidManifest.xml setting
The important point is that the "my.project.package" part must be changed to your own project's package name.
<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>
For reference, if you use Gradle, configure it as follows.
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
Register GCM in onCreate() of the first Activity launched (MainActivity) as follows.
@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
You must implement a service that extends GCMBaseIntentService. Its name must match the service class name registered in AndroidManifest. Preferably, stick to the name 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
Notes on GCM-related problems and their solutions.
No receivers for action com.google.android.c2dm.intent.REGISTRATION
If the error message No receivers for action com.google.android.c2dm.intent.REGISTRATION appears, add an action to the receiver's intent-filter as follows.
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
GcmBroadcastReceiver Class Not Found Exception
If the error message java.lang.ClassNotFoundException: com.google.android.gcm.GcmBroadcastReceiver appears, update android-suppert-v4.jar or write the full package path in the receiver's android:name attribute.
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
....
</receiver>
If the app does not crash but logcat prints an error log such as IntentReceiver com.google.android.gcm.GCMBroadcastReceiver@40233b88 that was originally registered here. Are you missing a call to unregisterReceiver()?, move the GCM service registration code to onCreate() of your app's application class.
Cannot resolve symbol GCM
- Cannot resolve symbol gcm (Android Studio 0.8.9)
- Cannot resolve com.google.android.gcm.GCMBaseIntentService; Android studio
In short, GCMBaseIntentService is obsolete. In the Android SDK Manager, clicking the Obsolete radio button at the bottom shows a package with the following name under Extras.
Libraries
See also
Favorite site
- Google Cloud Messaging for Android
- Wikipedia (en) Description of GCM
- GCM (Google Cloud Messaging)
- Implementing GCM Client
- Implementing GCM Server
Guide
- Sending push messages with Android GCM
- Android GCM (push server) notes
- Using GCM and APNS with Java 1
- Android GCM (Google Cloud Message) errors
- GCM development part 2 - Building an Android Application
Tutorial
- Using GCM 1 (Applying for the GCM service) 2
- Using GCM 2 (Implementing GCM on the device) 3
- Using GCM 3 (Building a GCM push server with JSP) 4
- GCM (2) – Building the client
- Using Google Cloud Messaging for Android (GCM)