2011-05-23 14 views
5

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?

+0

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

+0

También estoy enfrentando el mismo problema ... ayúdenme – Jomia

Respuesta

1

A veces, la solución está en la cara y que no lo ve, para los que tiene el mismo problema que yo, el problema estaba en el manifiesto, no escribo bien los paquetes de nombrar

+0

¿Puede proporcionarnos más? ¿información? Tengo la experiencia del mismo problema. No veo ningún problema en mi manifiesto. – paulpooch

2

Tuve el mismo problema y lo solucioné.

aquí es un código incorrecto

<receiver android:name=".MyC2DMReceiver" 
      android:permission="com.google.android.c2dm.permission.SEND"> 
     <intent-filter> 
      <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 
      <category android:name="com.package.myapp" /> 
     </intent-filter> 
     <intent-filter> 
      <action android:name="com.google.android.c2dm.permission.RECEIVE" /> 
      <category android:name="com.package.myapp" /> 
     </intent-filter> 
    </receiver> 

tuve escribir intención en lugar de permiso

com.google.android.c2dm.permission.RECEIVE => com.google.android.c2dm.intent.RECEIVE 

y luego funcionó correctamente por lo que el nombre del paquete de RECIBIR estaba mal

código correcto

<receiver android:name=".MyC2DMReceiver" 
      android:permission="com.google.android.c2dm.permission.SEND"> 
     <intent-filter> 
      <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 
      <category android:name="com.package.myapp" /> 
     </intent-filter> 
     <intent-filter> 
      <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
      <category android:name="com.package.myapp" /> 
     </intent-filter> 
    </receiver> 
Cuestiones relacionadas