2012/02/16

[C#] Android C2DM

internal static bool sendAndroidNotification(string message, string registrationID)
{
    const String ClientLoginURL = @"https://www.google.com/accounts/ClientLogin";
    const String C2DMServerURL = @"http://android.apis.google.com/c2dm/send";
    string collapseKey = DateTime.Now.ToShortDateString();

    String AuthTokenParams =
        @"accountType=GOOGLE&Email=" + Properties.Settings.Default.AndroidSenderEmail   // your sender email
        + "&Passwd=" + Properties.Settings.Default.AndroidSenderPassword    // your sender password
        + "&service=ac2dm";
    string authToken = getAndroidAuthToken(ClientLoginURL, AuthTokenParams);

    Dictionary<stringstring> data = new Dictionary<stringstring>();
    data.Add("data.msg"HttpUtility.UrlEncode(message));  // use UrlEncode() so that I can push messages other than English (like Chinese)

    return sendAndroidPushMessage(C2DMServerURL, registrationID, collapseKey, authToken, data);
}

private static string getAndroidAuthToken(string url, string parameters)
{
    string auth = "";
    HttpWebRequest oWebRequest = (HttpWebRequest)WebRequest.Create(url);
    oWebRequest.Method = "POST";
    oWebRequest.ContentLength = parameters.Length;
    oWebRequest.ContentType = "application/x-www-form-urlencoded";

    using (StreamWriter oWriter = new StreamWriter(oWebRequest.GetRequestStream()))
    {
        oWriter.Write(parameters);
    }

    using (HttpWebResponse oWebResponse = (HttpWebResponse)oWebRequest.GetResponse())
    {
        using (StreamReader sr = new StreamReader(oWebResponse.GetResponseStream()))
        {
            string responseData = sr.ReadToEnd();
            if (oWebResponse.StatusCode == HttpStatusCode.OK)   //OK = 200
            {
                auth = responseData.Substring(responseData.IndexOf("Auth=") + 5);
            }
            else
                // error handling
        }
    }

    return auth;
}

private static bool sendAndroidPushMessage(String url, String registration_id, String collapse_key, String auth, Dictionary<StringString> data)
{
    bool flag = false;
    StringBuilder sb = new StringBuilder();

    sb.AppendFormat("registration_id={0}&collapse_key={1}", registration_id, collapse_key);
    foreach (string item in data.Keys)
    {
        if (item.Contains("data."))
            sb.AppendFormat("&{0}={1}", item, data[item]);
    }

    string message = sb.ToString();
    HttpWebRequest oWebRequest = (HttpWebRequest)WebRequest.Create(url);
    oWebRequest.Method = "POST";
    oWebRequest.ContentLength = message.Length;
    oWebRequest.ContentType = "application/x-www-form-urlencoded";
    oWebRequest.Headers.Add("Authorization: GoogleLogin auth=" + auth);

    using (StreamWriter oWriter = new StreamWriter(oWebRequest.GetRequestStream()))
    {
        oWriter.Write(message);
    }

    using (HttpWebResponse oWebResponse = (HttpWebResponse)oWebRequest.GetResponse())
    {
        using (StreamReader sr = new StreamReader(oWebResponse.GetResponseStream()))
        {
            string responseData = sr.ReadToEnd();
            if (oWebResponse.StatusCode == HttpStatusCode.OK)   // OK = 200
            {
                if (responseData.StartsWith("id="))
                    flag = true;
            }
            else if (oWebResponse.StatusCode == HttpStatusCode.ServiceUnavailable)    // 503
                Console.WriteLine("The server is temporarily unavailable, please try later");
            else if (oWebResponse.StatusCode == HttpStatusCode.Unauthorized)          // 401
                Console.WriteLine("The ClientLogin AUTH_TOKEN used to validate the sender is invalid");
            else
                // other error handling
        }
    }

    return flag;
}

4 comments:

  1. Hi,
    Thanks for sharing very useful codes.

    ReplyDelete
  2. Thank you so much for the codes. Im getting an error mismatchsenderId , i have used the correct email account, geting the auth token. What can be the reason?

    ReplyDelete
  3. Hi djk,

    I will guess the sender email & password doesn't match with what Google has.

    Remember:
    The Sender ID is an email account associated with the application's developer. Take a look of this:
    https://developers.google.com/android/c2dm/#arch

    And, don't forget you have to register and wait for approving to use the C2DM service. Take a look of this :
    https://developers.google.com/android/c2dm/#registering

    ReplyDelete
  4. i get "The remote server returned an error: (403) Forbidden."

    ReplyDelete