web-dev-qa-db-fra.com

GcmListenerService.onMessageReceived () non appelé

Je travaille actuellement sur l'implémentation des notifications GCM dans mon application. 

Le problème que je rencontre est que la méthode onMessageReceived() de mon implémentation GcmListenerService n'est pas appelée. Je reçois bien les données des serveurs GCM, car il génère automatiquement une notification (je souhaite la remplacer par ma propre notification à l'aide de la méthode onMessageReceived()), mais aucun de mes appels au journal n'est ensuite imprimé dans le journal.

JSON envoyé du serveur au serveur GCM

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

AndroidManifest.xml (partie GCM uniquement)

<!-- 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 (juste une empreinte rapide pour voir si elle est appelée)

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);
    }
}

Pas sûr que la méthode pour demander des jetons soit pertinente, mais je peux la poster si nécessaire.

Si une partie de la question n'est pas claire, faites-le moi savoir, je ne suis pas le meilleur pour expliquer.

14
Dan

Comme expliqué dans this problème Github qui est exactement votre problème:

De https://developers.google.com/cloud-messaging/server#notifications_and_data_messages "GCM affichera la partie de notification au nom de l'application client. Lorsque des données facultatives sont fournies, elles sont envoyées à l'application client une fois que l'utilisateur a cliqué sur la notification et ouvert l'application client . [...] Sur Android, la charge utile des données peut être récupérée dans l'intention utilisée pour lancer votre activité. "

Ainsi, les données sont transmises dans l'intention utilisée pour lancer l'activité, après que l'utilisateur a appuyé sur la notification . Cela signifie que vous devez effectuer les opérations suivantes:

  • Ajoutez un click_action à la clé de notification que vous envoyez du serveur: Ex. 

    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" }})
    

Consultez la référence pour le contenu de notification à l'adresse: https://developers.google.com/cloud-messaging/server-ref#notification-payload-support

  • Dans AndroidManifest.xml, ajoutez un filtre d'intention sur l'activité que vous souhaitez ouvrir une fois que l'utilisateur a cliqué sur la notification, avec le même nom d'action que celui utilisé pour la clé "click_action" côté serveur, par exemple:

    <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>
    
  • Obtenez les données de l'intention de votre méthode onCreate () _ ​​ou sur onNewIntent () si vous avez défini le launchMode sur singleTop pour l'activité que vous souhaitez lancer lorsque la notification est cliqué, par exemple:

    @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);
        } 
    }
    

J'ai testé cela et peux confirmer que cela fonctionne. (utilisant une connexion XMPP)

12
bitek

GcmListenerService.onMessageReceived () ne sera pas appelé si le message en aval (json) contient une notification. 

4
Zephyr

Pour recevoir le message dans onMessageReceived, vous devez définir le champ "données" de niveau supérieur dans votre objet de message. Le champ de notification est traité automatiquement et génère une notification. OnMessageReceived ne reçoit aucune des données du champ de notification.

Mettez à jour votre objet de message pour inclure un champ de données et onMessageReceived devrait être appelé:

 {
 "notification": {
 "titre": "Titre", 
 "message texte",
 "icon": "@drawable \/ic_notification", 
 "click_action": "OPEN_MAIN_ACTIVITY" 
 }, 
 "Les données": {
 "some_key": "some_value" 
 }, 
 "registration_ids": [
 "xxxx", "xxxx", "xxxx", "etc" 
 ] 
} 
3
Arthur Thompson

onMessageReceived appelé uniquement pour "données uniquement" Massages Push. 

0
Sujit Yadav