15

I'm trying to use the GCM service to send push notifications to my devices.

I've followed the Android Hive tutorial (which is now deprecated like many other questions and answers about this) for the server-side functions, which look to work as expected since I can get this kind of outputs :

{"multicast_id":9131068334342174816,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1377441098827443%1d84a26ff9fd7ecd"}]}

But according to some answers, receiving this response just means that the message has been accepted by GCM servers for sending, but not that it has been sent. So, as expected, my BroadcastReceiver doesn't receive anything.

Here's my BroadcastReceiver code :

public class GcmBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("gcm_debug", "PushReceiver onReceive called");

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

        String msgType = gcm.getMessageType(intent);

        if(!extras.isEmpty()){
            if(GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(msgType)){
                Log.i("gcm_debug", "Message send error");
            }else if(GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(msgType)){
                Log.i("gcm_debug", "Message deleted");
            }else if(GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(msgType)){
                Log.i("gcm_debug", "Message received : " + extras.toString());
            }
        }

        setResultCode(Activity.RESULT_OK);
    }

}

And my AndroidManifest :

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

<permission android:name="<MYAPP>.permission.C2D_MESSAGE"
            android:protectionLevel="signature" />
<uses-permission android:name="<MYAPP>.permission.C2D_MESSAGE" />

<!-- Require OpenGL ES2 for GMap -->
<uses-feature android:glEsVersion="0x00020000"
              android:required="true" />


<!-- Because this app is using the GCM library to send messages, the min SDK cannot be lower
than 8 -->
<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="18" />


<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/LovRTheme" >
    <receiver
        android:name=".GcmBroadcastReceiver"
        android:permission="com.google.android.gcm.c2dm.permission.SEND" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <!-- <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> -->
            <category android:name="<MYAPP>" />
        </intent-filter>
    </receiver>
    <service android:name=".GcmIntentService" />

And the server-side code :

    $url = "https://android.googleapis.com/gcm/send";
    $fields = array(
        'registration_ids' => array($dstRegId),
        'delay_while_idle' => true,
        'data' => array("message" => $message));

    $headers = array(
        'Authorization: key=' . $google_api_key,
        'Content-Type: application/json');

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

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

    $result = curl_exec($ch);
    if($result === FALSE){
        die("Curl failed");
    }
    curl_close($ch);

    echo $result;

I'm coding from home, so I assume that GCM would not have problems getting in and out of the network since GCM uses a kind of reverse-shell connection. Anyway, i don't receive any of the log output i'm expecting.

EDIT: After leaving my app running for a while, LogCat sent me the following outputs :

08-26 00:00:48.984  17966-17966/? D/GCM: Ignoring attempt to send heartbeat on dead connection.
08-26 00:01:49.000  17966-17966/? D/GCM: Ignoring attempt to send heartbeat on dead connection.
08-26 00:02:01.672      433-448/? W/BroadcastQueue: Permission Denial: broadcasting Intent { act=com.google.android.c2dm.intent.RECEIVE flg=0x10 pkg=<myApp> (has extras) } from com.google.android.gsf (pid=17966, uid=10003) requires com.google.android.gcm.c2dm.permission.SEND due to receiver com.navissal.lovr/com.navissal.lovr.GcmBroadcastReceiver
08-26 00:17:09.063  17966-17966/? D/GCM: Ignoring attempt to send heartbeat on dead connection.
08-26 00:18:09.086  17966-17966/? D/GCM: Ignoring attempt to send heartbeat on dead connection.
08-26 00:24:15.250    3936-3951/? V/meshclient: uri: [/beacon?e=wTkyFfdWFtlzOme7rNizVCtnUu9t3SbJgKCe72og-OhyhGIYab1QikytBeU2Nc02QwdDtqI4sX7HHU6GpDQL8zZdKXFXmCics6ZG-Jmr84yvMX1x9EqdyyW1UI6PEhoOb9MV4R_msQ_MEWFnwUzQrV-vGTycKtSNKMMIRE-zM1caIe__7hdu_UStbhz0dhl7cAFmHYF74IQI6EYFCEORxgV2Wts4Ls-hRWEKfEzuBhViND7TeCVpqUOhdVwGMnDO_Qwlo0rpuSNFegdfJCYY4L8fZJogPsXdQW2cFSZ2S0kujCH9uIrljFUTSGcM5GCFuJRq8vWiTP07MqpMq7h2fGGpXQvjImFcVP81erkVzvlYu3bNpjyQe6MhxSFEZrG37Kdp2Fd3liXFZzSjKlLILeYsDK9rRYqO8fEy3PH07et1HjqYWrH-v7wnjcQm6TtyZu914oR-dPBAwX9D3WvbdQlPlqxnuwJ1huUTwaiKotPLgrAzo3Mc5vI93VTs3row]
Community
  • 1
  • 1
Jivay
  • 1,034
  • 3
  • 10
  • 23
  • The server code is irrelevant to your question, since you got a successful response from Google. Can you include your client code? – Eran Aug 25 '13 at 15:58
  • client code is intended to receive only since it is a cross-system app and the server handles all the sending. which part of the code do you need ? – Jivay Aug 25 '13 at 16:42
  • The broadcast receiver and the intent service. – Eran Aug 25 '13 at 18:57
  • I only use the broadcast receiver since i don't feel the need to use an intent service, and the broadcast receiver code is already added. Should i have one ? – Jivay Aug 25 '13 at 20:56
  • I must have missed the broadcast receiver code. Does `onReceive` get called when you send a message from your server? You don't need an intent service. I asked about it because you have it declared in your manifest. – Eran Aug 25 '13 at 21:14
  • nope, doesn't get called, otherwise i should get a log output telling me that it has been called. Also, i just undeclared the intent service. According to logcat, the `GcmService` intent service is correctly started (with this log output : `GcmService start Intent { act=com.google.android.gms.INITIALIZE flg=0x10 pkg=com.google.android.gms cmp=com.google.android.gms/.gcm.GcmService } com.google.android.gms.INITIALIZE` ) – Jivay Aug 25 '13 at 21:55
  • The last LogCat you added to your question showed me the answer. – Eran Aug 26 '13 at 12:11
  • In our case all things were perfect but we were not receiving messages due to office firewall. The way to ensure that receiver is fine is change the version which triggers registration and if that message comes thro the receiver is perfect! Details of fw tweaking at https://developer.android.com/google/gcm/http.html – Mr. B Aug 20 '14 at 13:08
  • it may cause by the client code Your Android client/app should get a new reg id after app update the version.(ex. 1.0->1.1) Check the method "private String getRegistrationId(Context context) " in http://developer.android.com/google/gcm/client.html – Nevin Chen May 17 '15 at 09:38
  • 1
    "...which is now deprecated..." as is most GCM examples. Google quite recently added a new github repo with examples: https://github.com/google/gcm – akousmata Jun 08 '15 at 16:34

1 Answers1

14

Here's your error:

<receiver
    android:name=".GcmBroadcastReceiver"
    android:permission="com.google.android.gcm.c2dm.permission.SEND" >

It should be:

<receiver
    android:name=".GcmBroadcastReceiver"
    android:permission="com.google.android.c2dm.permission.SEND" >
Eran
  • 387,369
  • 54
  • 702
  • 768