Skip to content
Search

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:

${ANDROID_HOME}/extras/google/gcm/gcm-client/dist/gcm.jar

Google Developers Console

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

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.

Google Cloud Messaging for Android Library (Obsolete)

Libraries

See also

Favorite site

Guide

Tutorial

References


  1. JAVA_-_GCM_and_APNS.pdf ↩

  2. Android_use_gcm1.pdf ↩

  3. Android_use_gcm2.pdf ↩

  4. Android_use_gcm3.pdf ↩