GCM App empfängt Pushes nur sporadisch

  • Antworten:11
  • Bentwortet
Bastian Seidemann
  • Forum-Beiträge: 137

09.05.2014, 17:24:26 via Website

Hallo Leute,

Ich habe eine Chat Applikation geschrieben welche GCM benutzt um Push Benachrichtigungen über neue Nachrichten zu Empfangen.

Das ganze ist ein Gruppenchat.

Wenn Ich im selben Netz bin mit z.b einem zweiten Android Gerät und meiner App empfange ich Nachrichten mit allem drum und dran.

Auch wenn das nicht der Fall ist kommen sporadisch Nachrichten an.

Meistens ist es aber so dass Ich meine Internetverbindung trennen und neu verbinden muss.
Danach lädt er sofort die aktuelle Nachricht vom GCM Server nach.

Aber nicht vorher.

Hier mein Code:

PHP Server Side:

 <?php

$nachricht=$_POST['nachricht'];
$nachricht=utf8_encode($nachricht);
$name=$_POST['name'];
$zeit=$_POST['zeit'];

$con = mysql_connect("XXXXXXXXXX", "XXXXXXXXXXX","XXXXXXXXXXX";);
if(!$con){
die('MySQL connection failed');
}

$db = mysql_select_db("DB1640880";);
if(!$db){
die('Database selection failed');
}

$registration_ids = array();
$sql = "SELECT * FROM tblregistration";
$result = mysql_query($sql, $con);

while($row = mysql_fetch_assoc($result)){
array_push($registration_ids, $row['registration_id']);

}

// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';

$message = array("Notice" => $nachricht, "Zeit" => $zeit, "Name" => $name);
     $fields = array(
         'registration_ids' => $registration_ids,
     'delay_while_idle' => true,     


         'data' => $message,
     );


echo json_encode($registration_ids);


     $headers = array(
         'Authorization: key=AIzaSyD4-XXXXXXXXXXc0Qa5fnl3lqMlfBE',
         'Content-Type: application/json'
     );
     // Open connection
     $ch = curl_init();

     // Set the url, number of POST vars, POST data
     curl_setopt($ch, CURLOPT_URL, $url);

     curl_setopt($ch, CURLOPT_POST, true);
     curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

     // Disabling SSL Certificate support temporarly
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

     curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

     // Execute post
     $result = curl_exec($ch);
     if ($result === FALSE) {
         die('Curl failed: ' . curl_error($ch));
     }

     // Close connection
     curl_close($ch);
     echo $result;

?>

GCM Broadcastreceiver:

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    // Explicitly specify that GcmIntentService will handle the intent.
    ComponentName comp = new ComponentName(context.getPackageName(),
            GcmIntentService.class.getName());
    // Start the service, keeping the device awake while it is launching.
    startWakefulService(context, (intent.setComponent(comp)));
    setResultCode(Activity.RESULT_OK);
}

}

GCM Intent Service:

package com.example.juzko;

import java.util.List;

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

import android.app.ActivityManager;
import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.SystemClock;
import android.os.Vibrator;
import android.provider.MediaStore.Audio;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.ListView;

public class GcmIntentService extends IntentService {

public SharedPreferences loginprefs;



private static final String TAG = "GcmIntentService";


public GcmIntentService() {
    super("XXXXXXXXXXX");

}

@Override
protected void onHandleIntent(Intent intent) {

    loginprefs = getSharedPreferences("login", 0);



    Bundle extras = intent.getExtras();
    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);

    String messageType = gcm.getMessageType(intent);

    if (!extras.isEmpty()) {

        Log.i("wird durchlaufen", "wird durchlaufen");
        if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
                .equals(messageType)) {

        } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
                .equals(messageType)) {


        } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
                .equals(messageType)) {

            for (int i = 0; i < 3; i++) {
                Log.i(TAG,
                        "Working... " + (i + 1) + "/3 @ "
                                + SystemClock.elapsedRealtime());
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                }
            }









            Intent i = new Intent("speedExceeded");
            i.putExtra("nachricht", extras.getString("Notice"));
            i.putExtra("zeit", extras.getString("Zeit"));
            i.putExtra("name", extras.getString("Name"));
            LocalBroadcastManager.getInstance(this).sendBroadcast(i);

            Log.i(TAG, "Received: " + extras.toString());

        }
    }

    GcmBroadcastReceiver.completeWakefulIntent(intent);
}

}

Manifest:

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android&quot;
package="com.example.juzko"
android:versionCode="1"
android:versionName="1.0" >

&lt;uses-sdk
    android:minSdkVersion=&quot;14&quot;
    android:targetSdkVersion=&quot;18&quot; /&gt;

&lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt;
&lt;uses-permission android:name=&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot; /&gt;
&lt;uses-permission android:name=&quot;android.permission.READ_EXTERNAL_STORAGE&quot; /&gt;
&lt;uses-permission android:name=&quot;android.permission.RECEIVE_BOOT_COMPLETED&quot; /&gt;
&lt;uses-permission android:name=&quot;com.android.alarm.permission.SET_ALARM&quot; /&gt;
&lt;uses-permission android:name=&quot;android.permission.VIBRATE&quot; /&gt;
&lt;uses-permission android:name=&quot;android.permission.GET_TASKS&quot; /&gt;
&lt;uses-permission android:name=&quot;android.permission.ACCESS_NETWORK_STATE&quot; /&gt;
&lt;uses-permission android:name=&quot;android.permission.BATTERY_STATS&quot; /&gt;
&lt;uses-permission android:name=&quot;android.permission.CAMERA&quot; /&gt;
&lt;uses-permission android:name=&quot;android.permission.ACCESS_WIFI_STATE&quot; /&gt;
&lt;uses-permission android:name=&quot;android.permission.GET_ACCOUNTS&quot; /&gt;
&lt;uses-permission android:name=&quot;android.permission.WAKE_LOCK&quot; /&gt;
&lt;uses-permission android:name=&quot;com.google.android.c2dm.permission.RECEIVE&quot; /&gt;

&lt;permission
    android:name=&quot;com.example.juzko.permission.C2D_MESSAGE&quot;
    android:protectionLevel=&quot;signature&quot; /&gt;

&lt;uses-permission android:name=&quot;com.example.juzko.permission.C2D_MESSAGE&quot; /&gt;
&lt;uses-permission android:name=&quot;android.permission.ACCESS_WIFI_STATE&quot; /&gt;

&lt;application
    android:allowBackup=&quot;true&quot;
    android:icon=&quot;@drawable/ic_launcher&quot;
    android:label=&quot;@string/app_name&quot;
    android:theme=&quot;@style/AppTheme&quot; &gt;
    &lt;activity
        android:name=&quot;com.example.juzko.MainActivity&quot;
        android:label=&quot;@string/app_name&quot;
        android:launchMode=&quot;singleTop&quot;
        android:screenOrientation=&quot;portrait&quot;
        android:windowSoftInputMode=&quot;adjustUnspecified&quot; &gt;
    &lt;/activity&gt;
    &lt;activity
        android:name=&quot;com.example.juzko.Chatroom&quot;
        android:label=&quot;@string/title_activity_mitglieder&quot;
        android:launchMode=&quot;singleTop&quot;
        android:screenOrientation=&quot;portrait&quot;
        android:theme=&quot;@android:style/Theme.Holo.Light.NoActionBar.Fullscreen&quot; &gt;
    &lt;/activity&gt;
    &lt;activity
        android:name=&quot;com.example.juzko.Aktivitaeten&quot;
        android:label=&quot;@string/title_activity_aktivitaeten&quot;
        android:screenOrientation=&quot;portrait&quot;
        android:theme=&quot;@android:style/Theme.Holo.Light.NoActionBar.Fullscreen&quot; &gt;
    &lt;/activity&gt;
    &lt;activity
        android:name=&quot;com.example.juzko.Bierliste&quot;
        android:label=&quot;@string/title_activity_bierliste&quot;
        android:screenOrientation=&quot;portrait&quot;
        android:theme=&quot;@android:style/Theme.Holo.Light.NoActionBar.Fullscreen&quot; &gt;
    &lt;/activity&gt;
    &lt;activity
        android:name=&quot;com.example.juzko.SPS&quot;
        android:label=&quot;@string/title_activity_sps&quot;
        android:screenOrientation=&quot;portrait&quot;
        android:theme=&quot;@android:style/Theme.Holo.Light.NoActionBar.Fullscreen&quot; &gt;
        &lt;intent-filter&gt;
            &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;

            &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
        &lt;/intent-filter&gt;
    &lt;/activity&gt;
    &lt;activity
        android:name=&quot;com.example.juzko.Login&quot;
        android:label=&quot;@string/title_activity_login&quot;
        android:screenOrientation=&quot;portrait&quot;
        android:theme=&quot;@android:style/Theme.DeviceDefault.Light.NoActionBar.Fullscreen&quot;
        android:windowSoftInputMode=&quot;adjustPan&quot; &gt;
    &lt;/activity&gt;
    &lt;activity
        android:name=&quot;com.example.juzko.StartAtBootServiceReceiver&quot;
        android:label=&quot;@string/title_activity_start_at_boot_service_receiver&quot; &gt;
    &lt;/activity&gt;

    &lt;meta-data
        android:name=&quot;com.google.android.gms.version&quot;
        android:value=&quot;@integer/google_play_services_version&quot; /&gt;

    &lt;receiver
        android:name=&quot;com.example.juzko.StartAtBootServiceReceiver&quot;
        android:enabled=&quot;true&quot;
        android:exported=&quot;false&quot; &gt;
        &lt;intent-filter&gt;
            &lt;action android:name=&quot;android.intent.action.BOOT_COMPLETED&quot; /&gt;
        &lt;/intent-filter&gt;
    &lt;/receiver&gt;

    &lt;activity
        android:name=&quot;com.example.juzko.PicPreview&quot;
        android:label=&quot;@string/title_activity_pic_preview&quot;
        android:theme=&quot;@android:style/Theme.DeviceDefault.Light.NoActionBar.Fullscreen&quot; &gt;
    &lt;/activity&gt;

    &lt;receiver
        android:name=&quot;com.example.juzko.GcmBroadcastReceiver&quot;
        android:permission=&quot;com.google.android.c2dm.permission.SEND&quot; &gt;
        &lt;intent-filter&gt;

            &lt;!-- Receives the actual messages. --&gt;
            &lt;action android:name=&quot;com.google.android.c2dm.intent.RECEIVE&quot; /&gt;
            &lt;!-- Receives the registration id. --&gt;
            &lt;action android:name=&quot;com.google.android.c2dm.intent.REGISTRATION&quot; /&gt;

            &lt;category android:name=&quot;com.example.juzko&quot; /&gt;
        &lt;/intent-filter&gt;
    &lt;/receiver&gt;
    &lt;receiver android:name=&quot;com.example.juzko.NetworkChangeReceiver&quot; &gt;
        &lt;intent-filter&gt;
            &lt;action android:name=&quot;android.net.conn.CONNECTIVITY_CHANGE&quot; /&gt;
        &lt;/intent-filter&gt;
    &lt;/receiver&gt;

    &lt;service
        android:name=&quot;com.example.juzko.GcmIntentService&quot;
        android:enabled=&quot;true&quot; /&gt;

    &lt;activity
        android:name=&quot;com.example.juzko.BierAdapter&quot;
        android:label=&quot;@string/title_activity_bier_adapter&quot; &gt;
    &lt;/activity&gt;
&lt;/application&gt;

</manifest>

Hat jemand eine idee woran es scheitert?

Hab delay_while_idle sowohl auf true als auch false versucht.

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

10.05.2014, 15:17:23 via Website

Ich kenne das problem, meist liegt es daran das der WLAN rooter die Connections nach ca 5 minuten schließt. Das heisst es dauert eine weile bis der GCM Hartbeat das wieder öffnet. du kannst aber manuell den Hartbeat auslösen.
Selbiges verhalten kann man hin und wieder bei WA oder anderen APPs beobachten.

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Bastian Seidemann
  • Forum-Beiträge: 137

10.05.2014, 16:19:53 via App

Moin Moin,

Danke für eure Antworten.

Wie kann ich am besten den heartbeat manuell auslösen?

— geändert am 10.05.2014, 16:20:16

Antworten
Bastian Seidemann
  • Forum-Beiträge: 137

11.05.2014, 12:07:31 via App

Okay ich sende nun alle 2 Minuten einen heartbeat (leere gcm message) zum Server

Das funktioniert wunderbar.

Leider frisst es Sehr viel Batterie.

Ein Intervall von 3 Minuten ist schon zu lang und die Verbindung wird getrennt und das normale Intervall wird wieder aufgenommen.

Ideen oder muss ich damit leben?

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

11.05.2014, 13:41:54 via Website

Wenn jede APP so was macht hat der User keinen Spaß am gerät, ich würde eher versuchen den Hartbeat dann zu senden wenn der User die APP nutzt. Wenn das Device schläft sollte es eh egal sein ob 10 -15 Minuten delay sind.

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Bastian Seidemann
  • Forum-Beiträge: 137

11.05.2014, 13:46:29 via App

Okay ist eine Überlegung wert.

Aber die leere gcm message ist schon der beste Weg einen heartbeat zu senden?

Antworten
Markus B.
  • Forum-Beiträge: 636

11.05.2014, 15:22:30 via App

Bastian Seidemann

Okay ist eine Überlegung wert.

Aber die leere gcm message ist schon der beste Weg einen heartbeat zu senden?

Da die GCM API sonst keine alternative bietet, ja. Das Problem hier liegt ja wie beschrieben am Verhalten der einzelnen Router und da kannst du halt wenig machen. 100% tige Lösung ist halt ein manueller heartbeat, welcher enorm aufs Akku geht.
Dazu empfehle ich noch folgende Links:
http://developer.android.com/training/efficient-downloads/efficient-network-access.html
DevBytes: Efficient Data Transfers - Understandin…: http://youtu.be/cSIB2pDvH3E

Gruß

Antworten
Bastian Seidemann
  • Forum-Beiträge: 137

11.05.2014, 18:52:37 via Website

Aber wie macht Whatsapp das Ganze?
Die Batterie wird nicht allzu stark beansprucht aber dennoch kommen die Nachrichten in einer Reichweite von sofort bis 5 Minuten.

Was mich irritiert ist folgendes (Vielleicht versteh ich das auch falsch):

Es ist ja ein Chat.

Das heißt:

  1. User X sendet eine Nachricht raus (Die Verbindung zum GCM Server steht).
  2. User Y ist im Wifi und er befindet sich im Timeout (Intervall ja im Wifi alle 15 Minuten)
  3. User Y's Timeout ist nach 15 Minuten vorbei und er bekommt die Nachricht zugestellt. Er antwortet auch direkt.
  4. Zu der Zeit wo User Y die Antwort sendet ist User X in seinem Timeout und bekommt die Nachricht nicht direkt sondern auch nach 15 Minuten.
  5. Ergebnis: Bis 2 Nachrichten gesendet und bei beiden angekommen ist dauert es 30 Minuten.

Ist das so richtig interpretiert?

— geändert am 11.05.2014, 18:54:17

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

11.05.2014, 19:14:06 via Website

GCM ist kein Mittel um fast in Echtzeit Nachrichten zu senden, das verstehen viele falsch.
Whatsapp hat ebenfalls dieses Problem, mir ist das schon oftmals aufgefallen.
Ist aber meist nicht schlimm. Ich würde z.b nicht allein auf GCM oder APS aufbauen lassen sondern wenn beide Online sind auf Jabber oder dergleichen setzen.

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Bastian Seidemann
  • Forum-Beiträge: 137

11.05.2014, 19:35:11 via Website

Okay ich verstehe, Es geht um einen Gruppenchat.

Das bedeutet Diejenigen die Online sind sollen die Nachrichten möglichst präzise bekommen.
Die die es nicht sind bekommen Sie ja vom GCM Server eh nachgereicht

Was empfehlst du nun wenn alles fertig ist und alles nurnoch vom Intervall abhängt?

Antworten