it-swarm.com.ru

GcmListenerService.onMessageReceived () не вызывается

В настоящее время я работаю над внедрением уведомлений GCM в мое приложение. 

Проблема в том, что метод onMessageReceived() из моей реализации GcmListenerService не вызывается. Я получаю данные с серверов GCM в порядке, так как он автоматически генерирует уведомление (я хочу заменить его своим собственным уведомлением, используя метод onMessageReceived()), но после этого ни один из моих вызовов журнала не печатается в журнале.

JSON, который отправляется с сервера на сервер GCM

{
    "notification" : {
        "title" : "Title",
        "text" : "Message",
        "icon" : "@drawable\/ic_notification",
        "click_action" : "OPEN_MAIN_ACTIVITY"
    },
    "registration_ids":[
        "xxxx", "xxxx", "xxxx", "etc"
    ]
}

AndroidManifest.xml (только часть GCM)

<!-- GCM START -->
    <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.my.package" />
        </intent-filter>
    </receiver>

    <service
        Android:name=".Services.ListenerService"
        Android:exported="false" >
        <intent-filter>
            <action Android:name="com.google.Android.c2dm.intent.RECEIVE" />
        </intent-filter>
    </service>

    <service
        Android:name=".Services.IDListenerService"
        Android:exported="false">
        <intent-filter>
            <action Android:name="com.google.Android.gms.iid.InstanceID"/>
        </intent-filter>
    </service>
    <!-- GCM END -->

GcmListenerService (просто быстрая печать, чтобы увидеть, вызывается ли он вообще)

public class ListenerService extends GcmListenerService {

    private static final String TAG = "MyGcmListenerService";

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

Не уверен, что метод запроса токенов уместен, но я могу опубликовать его при необходимости.

Если какая-то часть вопроса неясна, дайте мне знать, я не лучший в объяснении.

14
Dan

Как объясняется в это Github проблема, которая является именно вашей проблемой:

От https://developers.google.com/cloud-messaging/server#notifications_and_data_messages "GCM отобразит часть уведомления от имени клиентского приложения. Когда предоставляются дополнительные данные, они отправляются в клиентское приложение, когда пользователь нажимает на уведомление и открывает клиентское приложение . [...] В Android полезная нагрузка данных может быть получена в намерении, используемом для запуска вашей деятельности. "

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

  • Добавьте click_action к ключу уведомления, который вы отправляете с сервера: Например. 

    send_queue.append({'to': REGISTRATION_ID,
                   'message_id': random_id(),
                   "notification" : {
                      "body" : "Hello from Server! What is going on? Seems to work!!!",
                      "title" : "Hello from Server!",
                      "icon" : "@drawable/ic_school_white_48dp",
                      "sound": "default",
                      "color": "#03A9F4",
                      "click_action": "OPEN_MAIN_ACTIVITY"
                    },
                   'data': { 'message': "Hello" }})
    

См. Ссылку на полезные данные уведомлений по адресу: https://developers.google.com/cloud-messaging/server-ref#notification-payload-support

  • В AndroidManifest.xml добавьте фильтр намерений к деятельности, которую вы хотите открыть, как только пользователь щелкнет по уведомлению, с тем же именем действия, которое вы использовали для клавиши "click_action" на стороне сервера, например:

    <activity
        Android:name=".ui.MainActivity"
        Android:label="@string/title_activity_main" >
        <intent-filter>
            <action Android:name="OPEN_MAIN_ACTIVITY" />
            <category Android:name="Android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
    
  • Получите данные из намерения вашего метода onCreate () _ ​​или для onNewIntent (), если вы установили для launchMode значение singleTop для действия, которое вы хотите запустить при уведомлении нажата, например:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        Intent intent = getIntent();
    
        if (intent.hasExtra(Constants.KEY_MESSAGE_TXT)) {
            String message = intent.getStringExtra(Constants.KEY_MESSAGE_TXT);
            Log.d(TAG, message);
        } 
    }
    

Я проверил это и могу подтвердить, что это работает. (используя соединение XMPP)

12
bitek

GcmListenerService.onMessageReceived () не будет вызываться, если нижестоящее сообщение (json) содержит уведомление. 

4
Zephyr

Чтобы получить сообщение в onMessageReceived, вам необходимо определить поле «data» верхнего уровня в вашем объекте сообщения. Поле уведомления обрабатывается автоматически и генерирует уведомление, onMessageReceived не получает никаких данных в поле уведомления.

Обновите ваш объект сообщения, включив в него поле данных, и onMessageReceived должен быть вызван:

 {
 "уведомление": {
 "title": "Title", 
 "текстовое сообщение",
 "icon": "@drawable \/ic_notification", 
 "click_action": "OPEN_MAIN_ACTIVITY" 
 }, 
 "данные": {
 "some_key": "some_value" 
 }, 
 "registration_ids": [
 «хххх», «хххх», «хххх», «и т. д.» 
 ] 
} 
3
Arthur Thompson

onMessageReceived вызывается только для «только данных» Push-массажей. 

0
Sujit Yadav