
Ранее в Android использовался C2DM (Cloud to Device Messaging), как сервис доставки Push-уведомлений на устройство. Но 26 июня он был официально отменен гуглом. На его место пришел новый GCM (Google Cloud Messaging).
Похожие названия. Одинаковая роль. В чем же разница ?
- Для использования GCM, необходимо получить Simple API Key в консоли Google APIs.
- Для GCM нужно получить Sender ID. Он является эквивалентом электронной почты в C2DM. Получить его можно опять-таки из консоли Google APIs, а точнее из URL:
code.google.com/apis/console/#project:{SENDER_ID} - Уведомления в GCM имеют формат JSON вместе с простым текстом.
- GCM может отправлять уведомления сразу на несколько устройств.
- Теперь одно устройство с одним идентификатором регистрации может получать уведомления сразу с нескольких серверов.
- Теперь уведомления могут иметь время жизни до 4-х недель. GCM будет хранить их до истечения срока.
- Теперь можно отправлять уведомления до 4Кб с полезной нагрузкой. Это будет очень выгодно для реал-тайма различных чатов. Однако данный метод будет сильней кушать батарейку устройства.
- Теперь нет необходимости передавать идентификатор устройства на сервер, чтобы избежать повторных регистраций одного устройства. Канонический идентификатор регистрации определяется GCM по последней регистрации устройства. И если сервер отправит уведомление со старым идентификатором, то GCM вернет канонический (последний) идентификатор, на который надо будет заменить старый.
Настройка GCM
Начнем с Android Manifest
Сначала нужно прописать разрешения:
<uses-permission android:name="android.permission.WAKE_LOCK"/> <permission android:name="{package}.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="{package}.permission.C2D_MESSAGE" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
Затем ресивер и сервис:
<receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" > <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> <category android:name="{package}" /> </intent-filter> </receiver> <service android:name=".GCMIntentService" />
* {package} заменить на ваш пакет (у меня com.habrahabr.gcm)
Затем в корневом каталоге пакета создаем класс GCMIntentService, наследуемый от GCMBaseIntentService:
package {package}; import android.app.Activity; import android.app.IntentService; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; import com.google.android.gcm.GCMBaseIntentService; public class GCMIntentService extends GCMBaseIntentService { private static final String TAG = "GCMIntentService"; public GCMIntentService() { super(GCMConfig.SENDER_ID); } @Override protected void onRegistered(Context context, String registrationId) { Log.i(TAG, "Device registered"); // Здесь мы должны отправить registrationId на наш сервер, чтобы он смог на него отправлять уведомления } @Override protected void onUnregistered(Context context, String registrationId) { Log.i(TAG, "Device unregistered"); } @Override protected void onMessage(Context context, Intent intent) { Log.i(TAG, "Received new message"); } @Override protected void onDeletedMessages(Context context, int total) { Log.i(TAG, "Received deleted messages notification"); } @Override public void onError(Context context, String errorId) { Log.i(TAG, "Received error: " + errorId); } @Override protected boolean onRecoverableError(Context context, String errorId) { Log.i(TAG, "Received recoverable error: " + errorId); return super.onRecoverableError(context, errorId); } }
И уже после этого в главном активити прописываем:
// Делаем проверки GCMRegistrar.checkDevice(this); GCMRegistrar.checkManifest(this); // Достаем идентификатор регистрации final String regId = GCMRegistrar.getRegistrationId(this); if (regId.equals("")) { // Если отсутствует, то регистрируемся GCMRegistrar.register(this, GCMConfig.SENDER_ID); } else { Log.v("GCM", "Already registered: " + regId); }
Теперь все готово, за исключением отправки самих уведомлений с сервера, но думаю, что для одной статьи этого пока достаточно.
Исходные коды получившегося приложения
GCM Architectural Overview
GCM Advanced Topics
