Здорово, когда у твоего приложения есть возможность постоянно получать апдейты с сервера. Конечно, реализовать периодические сетевые запросы легко, мы с тобой такое не раз делали. Однако, если дюжина приложений будет постоянно стучаться к своим управляющим серверам, батарея телефона или планшета разрядится еще до полудня.

 

Введение

Чтобы программисты не изобретали велосипед, в мобильных устройствах появилась система Push-уведомлений. Это сервис коротких сообщений, которые отправляются централизованно через серверы вендора ОС. Разработчики операционки самостоятельно реализуют периодическую связь устройства с сервером так, чтобы и сообщения приходили вовремя, и ресурсы устройства максимально экономились. Режим энергосбережения, роуминг, оптимальная длина сессии — обо всем этом уже позаботились, создав технологию Push.

Компания Google разработала API под названием Google Cloud Messaging, он доступен как для Android, так и для iOS. Использовать этот сервис можно совершенно бесплатно, то есть даром. Посмотрим, что же это за зверь и чем он хорош!

Google Cloud Messaging работает на всех ОС Android версии 2.2 и выше. Он предоставляет возможность удаленно отправить сообщение в приложение, ранее установленное на мобильное устройство. Полезный объем данных ограничен четырьмя килобайтами, при этом содержание таких сообщений может быть произвольным: от текстового уведомления для пользователя до системных команд приложению. В случае если мобильное устройство не в сети или включен режим энергосбережения, GCM создаст очередь из сообщений и доставит их позднее.

 

Как это работает

Во многих устройствах на базе Android есть приложения от Google с различной функциональностью, за правильную работу Push-сообщений отвечает пакет Google Play Services. Если такой пакет установлен, устройство периодически обращается к серверу с запросом о наличии новых Push-сообщений. Частота таких запросов зависит от многих параметров: способа интернет-соединения, состояния батареи и прочего. При этом для экономии трафика у пользователя есть возможность вообще отключить такой сервис.

Push-серверы служат «прослойкой» между устройством-получателем и отправителем сообщения. От разработчика, использующего GCM, требуется составить сообщение, следуя несложному синтаксису, а затем отправить POST-запрос на сервер Google, который в дальнейшем самостоятельно доставит сообщение на устройство.

Отправленное на устройство Push-сообщение имеет единственного конечного адресата — это приложение с уникальным идентификатором, другие приложения доступа к нему не получат. Для обработки полученных сообщений в приложении нужно реализовать методы, доступные через Google Play Services. Этим сегодня и займемся.

Рис. 1. Схема работы Google Cloud Messaging
Рис. 1. Схема работы Google Cloud Messaging
 

Регистрация

Как ты уже мог догадаться, главное звено в сервисе GCM — это серверы Google. Облако от этой компании осуществляет пропускной контроль и берет на себя все хлопоты по доставке сообщений, поэтому первым шагом будет регистрация в системе.

Для работы с GCM требуется создать несколько ключей доступа, их выдают после регистрации приложения на сайте Google (ссылка есть во врезке). Нужно указать точное название приложения и полное имя проекта. В результате ты получишь два уникальных параметра: Server Key и Sender ID. Важный момент: если проект или название приложение изменятся, ключи придется генерировать заново.

Также на странице регистрации есть большая синяя кнопка Generation configuration files. Она сформирует конфиг-файл google-services.json, в котором зашиты все необходимые параметры для работы сервиса, в том числе ключи. Чтобы добавить этот конфиг-файл в проект, просто скопируй его в корень папки app, где лежат исходные коды приложения.

Приложение будет использовать готовые инструменты, реализованные в Google Play Services, поэтому нужно подключить дополнительные модули к проекту. В Android Studio это делается путем правки файлов Gradle: в конфиг проекта подгружаем класс Google Services, а в конфиге приложения — плагины GCM и Google Play.

classpath 'com.google.gms:google-services:2.0.0-alpha6'
apply plugin: 'com.google.gms.google-services'
compile "com.google.android.gms:play-services-gcm:8.3.0"
 

Манифест-файл

Теперь идем править манифест проекта. Чтобы сэкономить батарею, Android старается побыстрее отправлять устройство в сон, снижая расход батареи и уменьшая частоту процессора. Это может помешать передаче и приему данных, поэтому у приложения должна быть возможность воспрепятствовать такому маневру.

<uses-permission android:name="android.permission.WAKE_LOCK" />

Чтобы стать получателем Push-сообщений, нужно добавить разрешение под названием C2D_MESSAGE, при этом в параметре name должно быть полное имя пакета.

<permission android:name="com.pahomov.gcmproject.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.pahomov.gcmproject.permission.C2D_MESSAGE" />

В нашем приложении будут модули из Google Play Service, об этом нужно тоже написать в манифесте. Сервис GcmReceiver отвечает за прием сообщений от сервера, а также в случае необходимости помогает устройству не уйти в режим экономии энергии:

<receiver android:name="com.google.android.gms.gcm.GcmReceiver" android:exported="true" ...></receiver>

Обрати внимание, что еще совсем недавно (до октября прошлого года) Push-уведомления можно было отправить сервисом Cloud to Device Messaging, подключая соответствующее разрешение c2dm.permission.RECEIVE, теперь он окончательно закрыт.

 

Проверки

Как показывает практика использования различных API от Google, генерация ключей и устранение зависимостей — самые трудоемкие задачи. Реализация же логики API в проекте довольно проста: нужно только создать несколько объектов и переопределить их классы, отвечающие за получение и отправку данных. На устройстве может не быть приложений от Google, в этом случае придется отказаться от Push-сообщений. Проверка на наличие API выполняется следующим образом.

private boolean checkPlayServices() {
  GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
  int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
  if (resultCode = ConnectionResult.SUCCESS) {return true;}
}
 

Токен

Ввести приложение в элитный клуб получателей Push-сообщений поможет один из методов Google API. Вызвать его будет удобно, воспользовавшись классом IntentService. Так же как и его родительский класс Service, он позволяет выполнять в фоне различные ресурсоемкие задачи, например сетевые вызовы. Главное преимущество IntentService в том, что после выполнения всех задач он будет самостоятельно остановлен системой, тогда как обычный Service продолжит висеть в фоне, ожидая команды stopSelf() или stopService(). Класс регистрации в GCM назовем RegistrationIntentService.

public class RegistrationIntentService extends IntentService {
  ...
}

Собственно, разработчики Google все подготовили для нас, осталось только нажать большую красную кнопку и наслаждаться результатом. В GCM API есть класс InstanceID, способный самостоятельно сформировать сетевой пакет с регистрационными данными и отправить его на сервер. От разработчика требуется только указать уникальный идентификатор пакета (Sender ID, еще он иногда называется Project number). А если файл google-services.json был скопирован правильно, то переменная gcm_defaultSenderId сама появится в Android Studio.

protected void onHandleIntent(Intent intent) {
  InstanceID instanceID = InstanceID.getInstance(this);
  String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
  ...
}

Метод getToken возвращает еще один уникальный параметр — идентификатор устройства, на котором установлено приложение с включенным сервисом GCM. Этот токен пригодится чуть позже для отправки сообщений, поэтому его нужно как-то передать из приложения на сервер разработчика. В этот раз Google, к сожалению, не поможет, сетевую функциональность нужно реализовать самому. Но не так давно в статье о библиотеках я писал про Retrofit, тут она будет как раз к месту.

Компания Google рекомендует периодически обновлять токен, чтобы избежать его компрометации и использования злоумышленниками. Чтобы инициировать из приложения перевыпуск ключа, достаточно просто еще раз вызвать метод getToken. Еще можно с сервера отправить команду на обновления токена, за обработку такой команды в приложении отвечает класс InstanceIDListenerService. Наличие в приложении такого сервиса обязательно, без него GCM не заработает.

public class MyInstanceIDListenerService extends InstanceIDListenerService {}

В этом классе существует единственный метод onTokenRefresh, он будет вызван системой в тот момент, когда приложение получит команду на обновление. Основная задача этого метода — запустить IntentService, содержащий InstanceID.

public void onTokenRefresh() {
  Intent intent = new Intent(this, RegistrationIntentService.class);
  startService(intent);
}
 

Сообщения

Разберем теперь особенности формирования сообщения. В GCM есть возможность отправлять сообщения как с сервера, так и с мобильного устройства на другие устройства с таким же приложением. При этом логика построения запросов сохраняется, разница будет только в полях адреса и отправителя.

Продолжение доступно только подписчикам

Вариант 1. Оформи подписку на «Хакер», чтобы читать все материалы на сайте

Подписка позволит тебе в течение указанного срока читать ВСЕ платные материалы сайта. Мы принимаем оплату банковскими картами, электронными деньгами и переводами со счетов мобильных операторов. Подробнее о подписке

Вариант 2. Купи один материал

Заинтересовала информация, но нет возможности оплатить подписку? Тогда этот вариант для тебя! Обрати внимание: этот способ покупки доступен только для материалов, опубликованных более двух месяцев назад.


Оставить мнение

Check Also

Власти ЕС оштрафовали Google на 5 млрд долларов за антимонопольные нарушения

На этой неделе стало известно, что Еврокомиссия оштрафовала Google на рекордные 4,3 млрд е…