I am implementing GCM in my application. I have followed all the steps given in GCM tutorial from developer.android.com
I am able to get the register ID from GCM successfully, and I am passing this ID to my application server. So the registration step is performed successfully.
Now when my application server sends a PUSH message to my device, the server gets the message as SUCCESS=8 FAILURE=0, etc., i.e. Server is sending message successfully, but OnMessage getting called 8 times depends on the success value.
My device connected throw my organization wifi without any proxy settings.
So my question is: why I am receiving PUSH message from GCM as much time of Success value. Why Google is delivering that much time? What could be the reason?
My GCMBaseIntentService looks like
public class GCMIntentService extends GCMBaseIntentService {
public GCMIntentService() {
super(GCMActivity.SENDER_ID);
}
@Override
protected void onError(Context arg0, String arg1) {
Log.d("GCM", "RECIEVED A ERROR MESSAGE");
// TODO Auto-generated method stub
}
@Override
protected void onRegistered(Context arg0, String registrationId) {
//Send the registration id to my app server to store the reg id list
GCMActivity.sendRegIdtoApplicationServer(registrationId);
}
@Override
protected void onUnregistered(Context arg0, String registrationId) {
// TODO Auto-generated method stub
}
@Override
protected void onMessage(Context context, Intent intent) {
Log.d("GCM", "RECIEVED A MESSAGE");
// Get the data from intent and send to notificaion bar
String data = intent.getStringExtra("data");
String action = intent.getAction();
if((action.equals("com.google.android.c2dm.intent.RECEIVE"))) {
try {
JSONObject jsonObject = new JSONObject(data);
boolean updateStatus = jsonObject.getBoolean("update");
if (updateStatus) {
//Showing Notification to user
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
My Activity looks like
public class GCMActivity extends Activity {
public final static String SENDER_ID = "872355133485";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gcm);
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
GCMRegistrar.register(this, SENDER_ID);
} else {
// sendRegIdtoApplicationServer(regId);
Log.v("gh", "Already registered");
System.out.println("RegisterID:"+ regId);
}
}
And Manifest file will be
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.aspire.gcmsample"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<permission android:name="com.aspire.gcmsample.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.aspire.gcmsample.permission.C2D_MESSAGE" />
<!-- App receives GCM messages. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- GCM connects to Google Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" android:debuggable="true">
<activity
android:name=".GCMActivity"
android:label="@string/title_activity_gcm" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.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="com.aspire.gcmsample" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
</application>
</manifest>
Here is my server side code
Properties apHeaders = new Properties();
// Use your own credentials for the below three lines
apHeaders.put("Content-Type", "application/json");
apHeaders.put("Authorization","key="+apiKey);
/*String data = "{\"registration_ids\":"+ devicesList +", \"data\":" +
"{\"data\":{\"score\" : \"1-0\", \"scorer\" : \"Ronaldo\", \"time\" : \"44\"}}}";*/
// get all registration Device ID from database
ArrayList<String> deviceId = DBRegistration.getInstance().fetchRegId();
String data = "{\"registration_ids\":"+ deviceId +", \"data\":" +
"{\"data\":{\"update\" : \"true\", " +
"\"file\": \"http://192.168.4.210:8080/FileDownload/DownloadFile?path=GCMSample.apk\"}}}";
String result = DBRegistration.getInstance().sendRequest(url, data, apHeaders);**
System.out.println("responseC"+ result);
out.println(result);
out.flush();
String apServerUrl = "https://android.googleapis.com/gcm/send";
public String sendRequest(String apServerUrl, String payload, Properties headers) {
// Setup Http URL connection
HttpURLConnection connection = null;
// Enable proxy if it needed.
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_URL, PROXY_PORT));
try {
URL url = new URL(apServerUrl);
// Enable proxy if needed.
connection = (HttpURLConnection) url.openConnection(proxy);
//connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
Object[] keys = headers.keySet().toArray();
for (int i = 0; i < keys.length; i++) {
connection.setRequestProperty((String) keys[i],
(String) headers.get(keys[i]));
}
//connection.setRequestProperty("Content-Length", ""+ payload.length());
} catch (Exception e) {
System.out.println("Failed setting up HTTP Connection\n" + e);
}
// Send the Request
String line = "";
String returnedResponse = "";
BufferedReader reader = null;
System.out.println("Request: " + payload);
try {
OutputStream os = connection.getOutputStream();
os.write(payload.toString().getBytes("UTF-8"));
os.close();
int status = connection.getResponseCode();
if (status != 200) {
System.out.println("HTTP Error code " + status
+ " received, transaction not submitted");
reader = new BufferedReader(new InputStreamReader(connection
.getErrorStream()));
} else {
reader = new BufferedReader(new InputStreamReader(connection
.getInputStream()));
}
while ((line = reader.readLine()) != null) {
returnedResponse += line;
}
} catch (Exception e) {
returnedResponse = e.getMessage();
System.out.println(e);
} finally {
try {
if (reader != null)
reader.close();
if (connection != null)
connection.disconnect();
} catch (Exception e) {
returnedResponse = e.getMessage();
System.out.println(e);
}
}
System.out.println(returnedResponse);
return returnedResponse;
}
Response from GCM server to my app server.
{"multicast_id":6552291927399218343,"success":13,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1356332586480671%79fa3a68f9fd7ecd"},{"message_id":"0:1356332586480674%79fa3a68f9fd7ecd"},{"message_id":"0:1356332586481759%79fa3a68f9fd7ecd"},{"message_id":"0:1356332586480807%79fa3a68f9fd7ecd"},{"message_id":"0:1356332586481944%79fa3a68f9fd7ecd"},{"message_id":"0:1356332586480996%79fa3a68f9fd7ecd"},{"message_id":"0:1356332586481939%79fa3a68f9fd7ecd"},{"message_id":"0:1356332586482000%79fa3a68f9fd7ecd"},{"message_id":"0:1356332586481997%79fa3a68f9fd7ecd"},{"message_id":"0:1356332586481942%79fa3a68f9fd7ecd"},{"message_id":"0:1356332586482003%79fa3a68f9fd7ecd"},{"message_id":"0:1356332586481948%79fa3a68f9fd7ecd"},{"message_id":"0:1356332586480995%79fa3a68f9fd7ecd"}]}
What does your response send to your servers from GCM look like? It is possible that you have the same device registered 8 separate times with different ID's, which seems most likely reason to me.
You should also look at the code that you are sending to the GCM servers to ensure that you are not sending the same registration ID eight times.
The response format is documented here: https://developer.android.com/google/gcm/gcm.html#response
Based on that I would take a look and see if you are receiving any canonical Id's, which would help to show you that you have the same device registered multiple times. You can read more about what to do with canonical Id's here: android GCM get original id of canonical id
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With