title: Android: C2DM Invalid Registration Error
body: <p>Everything appears to work fine, until I try to push out a notification; the app gets a registration id, and the server gets an Auth code, but apparently the registration id is invalid.</p>
  
  <p>When I run the PHP code after getting the registration from the app, it returns <code>Error=InvalidRegistration</code></p>
  
  <p>I am going to post all of my code for both the C2DM implementation and the server side CURL requests.</p>
  
  <p>Inside OnCreate:</p>
  
  <pre><code>Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
  registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
  registrationIntent.putExtra("sender", "MYEMAIL");
  startService(registrationIntent);
  </code></pre>
  
  <p>C2DM class:</p>
  
  <pre><code>import java.net.URL;
  import android.content.BroadcastReceiver;
  import android.content.Context;
  import android.content.Intent;
  import android.content.SharedPreferences;
  import android.util.Log;
  import android.widget.Toast;
  
  public class C2DMReceiver extends BroadcastReceiver
  {
      @Override
      public void onReceive(Context context, Intent intent) {
          String receiver = context.getPackageName() + ".C2DMReceiver";
          intent.setClassName(context, receiver);
          context.startService(intent);
  
          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.
          } else if (intent.getStringExtra("unregistered") != null) {
              // unregistration done, new messages from the authorized sender will be rejected
          } else if (registration != null) {
              // Send the registration ID to the 3rd party site that is sending the messages.
              // This should be done in a separate thread.
              // When done, remember that all registration is done. 
              sendReg(registration, context);
              Toast.makeText(context, registration, Toast.LENGTH_SHORT).show();
          }
      }
  
      private void handleMessage(Context context, Intent intent)
      {
      }
  
      public void sendReg(String key, Context context)
      {
          //Send key to server, this works fine
      }
  }
  </code></pre>
  
  <p>PHP code:</p>
  
  <pre><code>&lt;?php
  // get Auth from Google ClientLogin
  $new = shell_exec("curl -d accountType=HOSTED_OR_GOOGLE -d Email=MYEMAIL -d Passwd=MYPASSWORD -d service=ac2dm -d source=MYSOURCE -k https://www.google.com/accounts/ClientLogin | grep Auth=");
  $auth = substr($new, 5); // "DQAAAKY..."
  
  $fp = fopen('/home/me/Desktop/test.txt','w');
  fputs($fp, $new."\nAuth: ".$auth."\n");
  
  // ID is from the app
  $id = "APA91b...";
  fputs($fp, "ID: ".$id."\n\n");
  
  $msg = "hello";
  
  // if I don't include ContentLength, Google tells me I need it
  $len = strlen("registration_id=".$id."&amp;data.message=".$msg."&amp;collapse_key=something");
  fputs($fp, "Len: ".$len."\n\n");
  
  $info = shell_exec("curl --header \"Content-Length: ".$len."\" --header \"Authorization: GoogleLogin auth=".$auth."\" -d registration_id=".$id." -d data.message=".$msg." -d collapse_key=something -k https://android.apis.google.com/c2dm/send");
  
  fputs($fp, $info); // "Error=InvalidRegistration"
  fclose($fp);
  ?&gt;
  </code></pre>