33

Ho letto molti post relativi a un problema GCM che riguarda alcune persone. Sembra che in alcuni dispositivi/router/gestori le notifiche subiscano ritardi. Ho riscontrato questo problema con il mio router: i messaggi sono arrivati ​​con molto ritardo sul WIFI, ma sono arrivati ​​istantaneamente quando ho disattivato il Wi-Fi e connesso alla rete mobile.Come evitare ritardi nei messaggi GCM Android/modifica heartbeat

Sembra che ci sia una soluzione alternativa che può essere eseguita dall'app Android. Qualcosa come aumentare il battito cardiaco che mantiene in vita la connessione GCM, o così.

Qualcuno può dirci cosa dovremmo fare per evitare il ritardo? Come possiamo mantenere la connessione con GCM da un'app per Android? Un esempio di codice (e dove e come usarlo) sarebbe davvero utile.

This post spiega il problema. Dice che "potremmo mantenere in vita la connessione con un ping ogni due minuti dal server GCM (che è gratuito)". Come possiamo farlo?

Grazie mille


Le seguenti applicazioni sembrano fare il trucco. Sorprendentemente, il primo non ha bisogno di alcun permesso, la seconda connessione a Internet e il terzo è solo per i telefoni radicate:

https://play.google.com/store/apps/details?id=at.pansy.droid.gcmWifiFix

https://play.google.com/store/apps/details?id=com.elotro.pushheartbeat

https://play.google.com/store/apps/details?id=com.andqlimax.pushfixer

risposta

1

"we could keep the connection alive with a ping every two minutes from the GCM server (which is free)". How can we do that?

È possibile farlo inviando un messaggio GCM dal proprio server a tutti i dispositivi su cui si desidera eseguire questo ping. È possibile inserire un carico utile speciale nel messaggio che verrebbe elaborato automaticamente dall'app sul dispositivo (senza visualizzare alcuna notifica). Tuttavia, tale ping riduce la durata della batteria dei dispositivi che utilizzano questa app.

+0

Grazie Eran. Non possiamo farlo perché dovremmo inviare troppe notifiche - abbiamo milioni di dispositivi registrati. Possiamo fare il "ping" dal dispositivo (dall'app per Android)? –

+1

@FerranMaylinch Questo potrebbe essere possibile. Non ho mai provato a inviare una notifica da un dispositivo a se stessa, ma non c'è motivo per cui non dovrebbe funzionare (dopo tutto il dispositivo ha il proprio ID di registrazione e tutto ciò che deve fare è postare una richiesta HTTP al server GCM) . L'unico problema è che funzionerà solo quando l'app è in esecuzione. – Eran

10

Non è necessario inviare l'heartbeat dal server GCM al telefono, è possibile forzare Android stesso a inviare prima l'heartbeat che altrimenti farebbe.

ho avuto uno sguardo al notifiche push Fixer app, che ho provato e ha lavorato per me, e sembra tutto quello che dovete fare è trasmettere le seguenti intenti:

com.google.android.intent.action.MCS_HEARTBEAT 
com.google.android.intent.action.GTALK_HEARTBEAT 

io non so perché sta mandando entrambi, puoi provarne solo uno e vedere se fa il trucco. Ecco il link all'app (io non sono lo sviluppatore): https://play.google.com/store/apps/details?id=com.andqlimax.pushfixer.noroot

36

Vorrei mettere questo come commento nella prima risposta ma non ho abbastanza reputazione.

Avevo un problema simile e l'ho risolto eseguendo il codice qui sotto prima di chiamare il mio servizio web.

context.sendBroadcast(new Intent("com.google.android.intent.action.GTALK_HEARTBEAT")); 
context.sendBroadcast(new Intent("com.google.android.intent.action.MCS_HEARTBEAT")); 

Spero che ti aiuti!

+1

dove posso aggiungere il codice sopra GcmBroadcastReceiver? – sasikumar

+0

Ovunque si abbia accesso all'oggetto di contesto (Applicazione, Attività, Servizio). Ad esempio, se lo si utilizza all'interno della propria attività basta chiamare getContext() e utilizzare il codice sopra. –

+0

ok grazie, funziona bene – sasikumar

2

Una soluzione alternativa se avete i permessi di root - È possibile controllare e modificare i tempi GCM battito cardiaco manualmente. Il valore predefinito è 900000 (15 minuti).Ho impostato su 240000 (4 minuti) per essere sicuro ed evitare timeout router di 5 minuti.

Check battito cardiaco (shell)

adb shell 
su 
sqlite3 /data/data/com.google.android.gsf/databases/gservices.db "SELECT * FROM main WHERE name ='gtalk_max_server_heartbeat_time';" 
sqlite3 /data/data/com.google.android.gsf/databases/gservices.db "SELECT * FROM main WHERE name LIKE 'gtalk_%heartbeat_ping_interval_ms';" 

tempo Variazione del battito cardiaco (shell)

sqlite3 /data/data/com.google.android.gsf/databases/gservices.db "UPDATE main SET value = '240000' WHERE name = 'gtalk_max_server_heartbeat_time' 
sqlite3 /data/data/com.google.android.gsf/databases/gservices.db "UPDATE main SET value = '240000' WHERE name LIKE 'gtalk_%heartbeat_ping_interval_ms' 

tempo Variazione del battito cardiaco (Android)

Process proc = Runtime.getRuntime().exec("su"); 
DataOutputStream os = new DataOutputStream(proc.getOutputStream()); 
os.writeBytes("sqlite3 /data/data/com.google.android.gsf/databases/gservices.db \"UPDATE main SET value = '240000' WHERE name = 'gtalk_max_server_heartbeat_time'\"\n"); 
os.writeBytes("sqlite3 /data/data/com.google.android.gsf/databases/gservices.db \"UPDATE main SET value = '240000' WHERE name LIKE 'gtalk_%heartbeat_ping_interval_ms'\"\n"); 
os.writeBytes("exit\n"); 
os.writeBytes("exit\n"); 
os.flush(); 
os.close(); 
proc.waitFor();