See the updated GCM API Docs as @morepork suggests.
For existing apps that extend a WakefulBroadcastReceiver, Google
recommends migrating to GCMReceiver and GcmListenerService. To
migrate:
In the app manifest, replace your GcmBroadcastReceiver with "com.google.android.gms.gcm.GcmReceiver", and replace the current service declaration that extends IntentService to the new GcmListenerService
Remove the BroadcastReceiver implementation from your client code
Refactor the current IntentService service implementation to use GcmListenerService
For details, see the example manifest and code samples in this page.
From their sample code, it's pretty easy to follow.
AndroidManifest.xml
<receiver
android:exported="true"
android:name="com.google.android.gms.gcm.GcmReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
<category android:name="com.example.client"/>
</intent-filter>
</receiver>
<service
android:name=".MyGcmListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
</intent-filter>
</service>
<service
android:name=".MyInstanceIdListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<service
android:name=".MyGcmRegistrationService"
android:exported="false">
</service>
MyGcmListenerService.java
public class MyGcmListenerService extends GcmListenerService {
@Override
public void onMessageReceived(String from, Bundle data) {
final String message = data.getString("message");
makeNotification(message);
}
}
MyGcmRegistrationService.java
public class MyGcmRegistrationService extends IntentService {
private static final String TAG = "MyRegistrationService";
private static final String GCM_SENDER_ID = "XXXXXXXXXXXX";
private static final String[] TOPICS = {"global"};
public MyGcmRegistrationService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
try {
synchronized (TAG) {
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(GCM_SENDER_ID,
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
sendTokenToServer(token);
subscribeTopics(token);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void subscribeTopics(String token) throws IOException {
for (String topic : TOPICS) {
GcmPubSub pubSub = GcmPubSub.getInstance(this);
pubSub.subscribe(token, "/topics/" + topic, null);
}
}
}
MyInstanceIdListenerService.java
public class MyInstanceIdListenerService extends InstanceIDListenerService {
public void onTokenRefresh() {
Intent intent = new Intent(this, MyGcmRegistrationService.class);
startService(intent);
}
}
Then you can replace your old registration code with just
Intent intent = new Intent(this, MyGcmRegistrationService.class);
startService(intent);