Блог веб-разработчика v 1.0.0
Symfony2, AngularJS, React, Gulp, PhpStorm и много других страшных слов

Push уведомления в Android через GCM

9 лет назад
29482 просмотра
Android GCM

Что за Push уведомления?

Это сообщения, поступающие от сервера к клиенту без запроса со стороны клиента. В кратце - если вам надо чтобы приложение реагировало мгновенно на какие-либо события на сервере, например, появление новости, то вы на правильном пути.

В кратце, весь процесс происходит так: ваше приложение отправляет запрос в GCM и получает строку-токен. Эту же строку приложение отправляет на свой (ваш) сервер, чтобы сервер запомнил этот токен, ассоциировал с каким-либо пользователем (например) и в будущем знал куда посылать сообщения.

Проще всего идти по руководству от Google, однако я его так просто не понял. У гугла всегда как-то неполюдски написано, а в интернете найти статью про подключение GCM к своему проекту оказалось не так то просто, т.к. все используют устаревшие методы (они работают, но мы то хотим следовать за новым).

Регистрация в Google API

Для начала нужно получить API ключ в Google Console. Идем по ссылке, попутно регистрируем аккаунт, если нужно. Создаем проект под наше приложение (название не важно).

Идем в раздел APIs & auth > APIs, выбираем Cloud Messaging for Android. Жмем Enable API.

Идем в раздел APIs & auth > Credentials. В разделе Public API access надимаем Create new Key > Server Key. Можете ввести IP адреса с которых будут поступать запросы. Запоминаем созданный ключ. В моем случае это: AIzaSyCT56IghciRgykwlX6Xr1v2jCOovHWY6h0.

Так же из ссылки в браузере берем ID проекта вида: 951430446448. Это будет значение SENDER_ID (объясню позже).

Зависимости Gradle

Работать будем в Android Studo. Она давно уже вышла из беты, работает в целом неплохо и более-менее стабильно.

В ваш gradle-файл добавляем (версию ставьте актуальную на ваше время, хотя что-то может поменяться):

dependencies {
  compile "com.google.android.gms:play-services-gcm:7.5.+"
}

Обратите внимание, что мы указываем в зависимостях только GCM. Можно указывать весь Play Services, но приложение раздуется еще больше без особой надобности.

Обновляем манифест

Обновите ваш AndroidManifest.xml в соответствии с тем, что указано ниже. Все элементы являются очень важными. Без разрешений или сервисов ничего работать не будет.

<manifest package="com.example.gcm" ...>

    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17"/>
    <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="com.example.gcm.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />

    <application ...>
        <receiver
            android:name="com.google.android.gms.gcm.GcmReceiver"
            android:exported="true"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <category android:name="com.example.gcm" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                <category android:name="com.example.gcm" />
            </intent-filter>
        </receiver>
        <service
            android:name="com.example.MyGcmListenerService"
            android:exported="false" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </service>
    </application>

</manifest>

Не забудьте заменить com.example на свое приложение. В том числе и в разрешениях.

Получение токена пользователя в Android приложении

Следующее чему мы должны научить наше приложение: регистрироваться в GCM и отдавать нам свой токен. Получение токена делается в пару строк:

InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(SENDER_ID,  GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

Где SENDER_ID - ID приложения, которое мы скопировали ранее из URL в браузере.

Переменную token нужно отправить на ваш сервер, откуда будут поступать сообщения. Как это делать - решайте сами. У меня был простой POST запрос, в результате которого в БД заносился указанный токен. Плюс ко всему я еще передавал email пользователя, чтобы лучше ориентироваться при тестировании.

Прием Push-уведомлений

Далее нам нужно научить приложение принимать сообщения. В манифесте мы зарегистрировали сервис, теперь реализуем его. Унаследуем гугловский сервис по приему сообщений:

package com.example;

import com.google.android.gms.gcm.GcmListenerService;

public class MyGcmListenerService extends GcmListenerService {
    @Override
    public void onMessageReceived(String from, Bundle data) {
        String message = data.getString("message");
        Log.d(TAG, "From: " + from);
        Log.d(TAG, "Message: " + message);
    }
}

Этот метод будет вызываться каждый раз как приходит новое Push-уведомление. Причем желательно сравнивать from с вашим SENDER_ID, чтобы быть уверенным, что сообщение пришло из нужного приложения.

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

Что еще почитать
Выезжающая панель на Android
10 лет назад
18032 просмотра
Вчера мне понадобилось сделать панель наподобие стандартной верхней панели Android, той самой которую вы ежедневно вытаскиваете пальцем из-за верхнего края экрана. Поскольку опыта для написания собственного View подобного рода у меня нет, я начал поиск готовых решений.
Что ожидает веб-разработчика в мире Android?
10 лет назад
13706 просмотров
Где-то месяц назад занялся разработкой своего первого мобильного приложения. Каковы же впечатления от перехода из веба в мир мобильной разработки?