Cuando envío una notificación a un dispositivo, este dispositivo recibe el mensaje push, pero recibe un intento "com.google.android.c2dm.intent.REGISTRATION", no un "com.google.android" .c2dm.intent.RECEIVE ". Si intento enviar una segunda notificación, obtengo el error "No registrado" de Google.Android c2dm automáticamente no registrado
El dispositivo se registra bien (supongo), porque obtengo el token de autenticación "APA91 ... -119 caracteres-".
Aquí está mi código para comenzar a registrar el dispositivo:
Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
registrationIntent.putExtra("sender", "EMAIL");
startService(registrationIntent);
El remitente (esto se hace en el dispositivo Android):
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("https://www.google.com/accounts/ClientLogin");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("Email", "SAME AS LOGIN"));
nameValuePairs.add(new BasicNameValuePair("Passwd", "****"));
nameValuePairs.add(new BasicNameValuePair("accountType", "HOSTED_OR_GOOGLE"));
nameValuePairs.add(new BasicNameValuePair("source","Google-cURL-Example"));
nameValuePairs.add(new BasicNameValuePair("service", "ac2dm"));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null) {
Log.e("C2DM", line);
if (line.startsWith("Auth=")) {
s = line.substring(5);//LOGIN TOKEN
Log.i("C2DM", "Token get: "+ s);
String auth_key = s; /* GETTING THE AUTH TOKEN FROM SERVER */
StringBuilder postDataBuilder = new StringBuilder();
postDataBuilder.append(PARAM_REGISTRATION_ID).append("=").append(auth_key);
postDataBuilder.append("&").append(PARAM_COLLAPSE_KEY).append("=").append("0");
postDataBuilder.append("&").append("data.info").append("=").append(URLEncoder.encode("Invitar", UTF8));
URLEncoder.encode(telephonyManager.getDeviceId(), UTF8));
byte[] postData = postDataBuilder.toString().getBytes(UTF8);
URL url = new URL("https://android.clients.google.com/c2dm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
conn.setRequestProperty("Content-Length",Integer.toString(postData.length));
conn.setRequestProperty("Authorization", "GoogleLogin auth="+ auth_key);
OutputStream out = conn.getOutputStream();
out.write(postData);
out.close();
int responseCode = conn.getResponseCode();
Log.e("C2DM", String.valueOf(responseCode));
// Validate the response code
if (responseCode == 401 || responseCode == 403) {
Log.e("C2DM", "Unauthorized - need token");
}
// Check for updated token header
String updatedAuthToken = conn.getHeaderField(UPDATE_CLIENT_AUTH);
if (updatedAuthToken != null && !auth_key.equals(updatedAuthToken)) {
Log.i("C2DM","Got updated auth token from datamessaging servers: "+ updatedAuthToken);
Editor edit = prefManager.edit();
edit.putString(AUTH, updatedAuthToken);
}
String responseLine = new BufferedReader(new InputStreamReader(conn.getInputStream())).readLine();
if (responseLine == null || responseLine.equals("")) {
Log.i("C2DM", "Got " + responseCode+ " response from Google AC2DM endpoint.");
throw new IOException("Got empty response from Google AC2DM endpoint.");
}
String[] responseParts = responseLine.split("=", 2);
if (responseParts.length != 2) {
Log.e("C2DM", "Invalid message from google: " + responseCode+ " " + responseLine);
throw new IOException("Invalid response from Google "+ responseCode + " " + responseLine);
}
if (responseParts[0].equals("id")) {
Log.i("C2DM", "Successfully sent data message to device: "+ responseLine);
retval = 1;
}
if (responseParts[0].equals("Error")) {
String err = responseParts[1];
Log.w("C2DM","Got error response from Google datamessaging endpoint: "+ err);
// No retry.
throw new IOException(err);
}
return sendMessage();
}
}
} catch (IOException e) {
e.printStackTrace();
}
Mi receptor:
public void onReceive(Context context, Intent intent) {
Log.d("C2DM", "Intent recieved: "+intent.getAction());
if (intent.getAction().equals("com.google.android.c2dm.intent.REGISTRATION")) {
handleRegistration(context, intent);
} else if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {
handleMessage(context, intent);
}
}
private void handleRegistration(Context context, Intent intent) {
String registration = intent.getStringExtra("registration_id");
if (intent.getStringExtra("error") != null) {
// Registration failed, should try again later.
Log.d("C2DM", "registration failed");
String error = intent.getStringExtra("error");
if(error == "SERVICE_NOT_AVAILABLE"){
Log.d("c2dm", "SERVICE_NOT_AVAILABLE");
}else if(error == "ACCOUNT_MISSING"){
Log.d("c2dm", "ACCOUNT_MISSING");
}else if(error == "AUTHENTICATION_FAILED"){
Log.d("c2dm", "AUTHENTICATION_FAILED");
}else if(error == "TOO_MANY_REGISTRATIONS"){
Log.d("c2dm", "TOO_MANY_REGISTRATIONS");
}else if(error == "INVALID_SENDER"){
Log.d("c2dm", "INVALID_SENDER");
}else if(error == "PHONE_REGISTRATION_ERROR"){
Log.d("c2dm", "PHONE_REGISTRATION_ERROR");
}
} else if (intent.getStringExtra("unregistered") != null) {
//HERE IS WHERE ARRIVES THE SEND NOTIFICATION (NOT THE UNREGISTER NOTIFICATION)
Log.d("C2DM", "unregistered: "+intent.getStringExtra("unregistered"));
} else if (registration != null) {
Log.d("C2DM", registration);
/* SENDING THE AUTH TOKET TO SERVER */
}
}
Hago las notificaciones push en el dispositivo porque si lo hago en el lado del servidor, siempre obtengo un error de "InvalidRegistration" .
Lo extraño es que parece que me registro, pero cuando envío un mensaje de inserción, es como si Google cancelara el registro del dispositivo.
¿Alguna idea/sugerencia?
He mejorado el código, ahora, hago el servicio ac2dm en mi servidor (php), pero la respuesta es la misma, en el dispositivo recibo la petición para anular el registro. El código es el mismo que aquí: [link] (http://stackoverflow.com/questions/4121508/c2dm-implementation-php-code) – Guillem
También estoy enfrentando el mismo problema ... ayúdenme – Jomia