2012-12-12 13 views
40

Während auf einem kleinen Projekt zu arbeiten, die mit GCM integriert, ich auf ein bisschen eine seltsame Frage gestolpert.Google Cloud Messaging - Nachrichten manchmal nicht bis Netzwerkstatus empfangen geändert

Manchmal, wenn ich das Protokoll anschaue, um zu sehen, ob Nachrichten empfangen werden, scheinen Nachrichten nicht durchzugehen, bis ich den Netzwerkzustand geändert habe (IE ursprünglich auf WiFi, wenn ich WiFi abstelle und zu Mobile Daten gehe) , die Nachrichten kommen gut an). Nachdem ich den Netzwerkstatus geändert haben, starten Nachrichten völlig in Ordnung kommen, und das gleiche gilt, wenn ich den Netzwerkstatus wieder zu ändern, was vor ihm war (in diesem Fall, WiFi) die Nachrichten empfangen werden fortzusetzen.

Das Projekt selbst beinhaltet die Möglichkeit, beim Booten zu starten (startet den GCMBaseIntentService beim Booten), was wiederum einwandfrei funktioniert, und ich bin mir sicher, dass die App/Dienst ausgeführt wird, wenn ich die App manuell gestartet habe Problem tritt auf (die überprüft, um zu sehen, auch wenn der Dienst ausgeführt wird, und wenn es nicht läuft es und überprüft, ob es registriert ist).

Ist jemand anderes auf dieses Problem gestoßen oder hat er irgendwelche Hinweise, wie ich das lösen könnte? Ich bin nichts von viel Hilfe im Protokoll zwischen den Zeitnachrichten zu sehen, werden nicht empfangen und wenn sie (nach den Netzwerkstatus zu ändern). Ich habe durch die GCM docs gegangen und kann keine Erwähnung von Nachrichten sehe nicht aufgrund einer Auszeit (auf dem Gerät selbst) empfangen werden, oder alle Konfigurationsoptionen, die diese beeinflussen könnten.

Schätzen Sie jede Hilfe - ich kann Quelle zur Verfügung stellen, wenn es sein muss, obwohl es kaum von der Demo-App in der Android-SDK bereitgestellten abweicht.

+2

Ja, ich sehe ähnlich, wie andere auch. Der Empfang erfolgt sofort beim Einschalten, variable Verzögerung über 3g. Wenn Sie den Flugzeugmodus einschalten, dann werden Meldungen angezeigt. Ich habe einen Kommentar in der Google-Entwicklergruppe hinzugefügt (den ich im Moment nicht finden kann!). Mein Gerät ist ein Samsung Galaxy S2 – NickT

+0

Dank - ich verstehe, dass es eine leichte Verzögerung mit 3G im Vergleich zu WiFi sein wird, aber mein Punkt ist, dass Nachrichten manchmal überhaupt nicht ankommen..wie auch immer wenn ich das Netzwerk (dh von Wifi zu 3G oder umgekehrt) beginnen wieder zu erscheinen. Ich würde den Link zu dem Kommentar/Thema schätzen, das Sie als Referenz gepostet haben :) Danke ps. Ich bin auch auf einem Galaxy S2. – Seidr

+1

Hallo Der Link ist https://groups.google.com/forum/?fromgroups=#!topic/android-gcm/bsYumo68fsc. Mein Telefon ist mit O2. Ich bekomme immer die Nachrichten, aber es kann 30 Minuten dauern. Ich habe hier in London ein starkes (normalerweise H +) Signal. – NickT

Antwort

36

Ich habe dies auch bemerkt. Obwohl ich mich nicht mit dem eigentlichen Code beschäftigt habe, verstehe ich, warum das so ist.

GCM (und die meisten Push-Messaging-Dienste) funktionieren, indem ein langlebiger Socket für den Push-Benachrichtigungsserver von Google geöffnet bleibt. Der Socket wird geöffnet, indem "Heartbeat" -Nachrichten zwischen dem Telefon und dem Server gesendet werden.

Gelegentlich kann sich der Netzwerkstatus ändern und dieser Socket wird beschädigt (weil sich die IP-Adresse des Geräts ändert, z. B. von 3g auf wifi). Wenn die Meldung kommt, bevor die Buchse wieder hergestellt werden, dann wird das Gerät nicht sofort die Nachricht.

Die Wiederverbindung findet nur statt, wenn das Telefon bemerkt, dass der Socket defekt ist, was nur passiert, wenn es versucht, eine Heartbeat-Nachricht zu senden.

Wieder, nur mein grundlegendes Verständnis davon, wie es funktioniert und warum es passiert, und ich könnte falsch liegen.

+0

Akzeptiert Ihre Antwort, aufgrund der Tatsache, dass es derzeit keine Lösung dafür zu sein scheint, aber Ihre Antwort beschreibt am besten die Ursache des Problems. – Seidr

+0

Sie haben den Punkt, GCM behandelt nicht gut ein TCP-Timeout, siehe mehr: http: // Stackoverflow.com/questions/16749038/google-cloud-messaging-messages-entweder-empfangen-sofort-oder-mit-lange-verzögerung/18428357 # 18428357 – andQlimax

-4

in der GCMIntentSevice Klasse, wenn Sie Nachricht vom Server empfangen, wird onMessage Methode so zu dieser Zeit genannt Sie wie etwas tun ...

PowerManager pm = (PowerManager) getApplicationContext() 
       .getSystemService(Context.POWER_SERVICE); 
     WakeLock wakeLock = pm.newWakeLock(
         (PowerManager.SCREEN_BRIGHT_WAKE_LOCK 
           | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP),"TAG"); 
     wakeLock.acquire(); 

und Sie haben

hinzufügen <uses-permission android:name="android.permission.WAKE_LOCK" /> Erlaubnis in ihrer Manifest-Datei ..

dies den Trick tun soll ...

+1

Vielen Dank für Ihre Antwort, aber der lebendige Zustand ist nicht das Problem hier. Ich glaube, es hat damit zu tun, dass die langlebige Verbindung verloren geht und nicht rechtzeitig wiederhergestellt wird. – Seidr

1

Laut Ihrem Kommentar in der obigen Antwort und meiner Erfahrung mit GCM Push - Benachrichtigungen gibt es keinen Grund, dass, wenn Netzwerk (Internetverbindung) verfügbar ist, Sie keine Push - Benachrichtigungen erhalten sollten Anwendung für Push-Benachrichtigung wie dies versuchen, dies zu überprüfen, wenn dies wahr ist, sollten Sie Push-Benachrichtigungen erhalten

+0

hast du das versucht? –

19

Es gibt viele Ursachen für GCM-Nachrichtenverzögerungen. Wenn die Nachricht nach dem Ändern des Netzwerkstatus oder dem Aktivieren/Deaktivieren des Flugzeugmodus eintrifft, ist die wahrscheinlichste Ursache ein Netzwerk, das die Verbindung schließt, ohne FIN/RST zu senden.

GCM unterhält eine langlebige Verbindung - und stellt wieder her, wenn es weiß, dass die Verbindung unterbrochen wurde. Ein Router/AP/NAT soll ein FIN oder RST senden, um die TCP-Verbindung zu beenden - damit GCM und Server wissen, dass die Verbindung tot ist.

Aber eine Reihe von Routern und Mobilfunkbetreiber tun dies nicht, und dann muss GCM auf den Herzschlag verlassen, ~ 15 min auf Wifi, mehr auf dem Handy. Es gibt einen Kompromiss zwischen Batterielebensdauer/Netzwerknutzung und Herzschlagfrequenz.

+0

Schöne technische Erweiterung auf die eigentliche Ursache dafür. – Seidr

0

so, Wenn @theelfismike Denken wahr ist, kann ich so etwas wie:

ConnectivityManager cm = (ConnectivityManager) context 
      .getSystemService(Context.CONNECTIVITY_SERVICE); 

    NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); 
    if (null != activeNetwork) { 
     if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) 
      // here the network changed to Wifi so I can send a heartbeat to GCM to keep connection 

     if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) 
      //here the network changed to mobileData so I can send a heartbeat to GCM to keep connection 
    } 

ist meine Lösung gut?

+0

Unnötig, GCM macht das autonom –

Verwandte Themen