将消息从Google App Engine推送到C2DM服务器

时间:2011-12-17 08:33:50

标签: android google-app-engine servlets android-c2dm

我已经能够

  1. 获取服务器身份验证并将其保存到数据存储区;
  2. 将手机注册到c2dm服务器;
  3. 将ID发送到应用服务器,将应用程序c2dm重新注册ID保存到数据存储区。
  4. 现在我只想实现一个检索服务器令牌号的servlet。来自数据存储区的android和android应用程序regirstration id,并使用它们将消息推送到手机。

    这是servlet的代码:

    package com.visd.myfirstapp;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.net.URL;
    import java.net.URLEncoder;
    import java.util.Date;
    
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLSession;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.google.appengine.api.datastore.DatastoreService;
    import com.google.appengine.api.datastore.DatastoreServiceFactory;
    import com.google.appengine.api.datastore.Entity;
    import com.google.appengine.api.datastore.EntityNotFoundException;
    import com.google.appengine.api.datastore.Key;
    import com.google.appengine.api.datastore.KeyFactory;
    
    //import com.visd.myfirstapp.MessageUtil.CustomizedHostnameVerifier;
    
    public class Visd extends HttpServlet {
        private final static String AUTH = "authentication";
    
        private static final String UPDATE_CLIENT_AUTH = "Update-Client-Auth";
    
        public static final String PARAM_REGISTRATION_ID = "registration_id";
    
        public static final String PARAM_DELAY_WHILE_IDLE = "delay_while_idle";
    
        public static final String PARAM_COLLAPSE_KEY = "collapse_key";
    
        private static final String UTF8 = "UTF-8";
        public void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws IOException 
        {
            resp.setContentType("text/plain");
            Entity appRegIdEntity = null;
            Entity serverTokenEntity = null;
            int RetCode = 0;
            String message = "Congrats C2DM process completed";
            Key appRegIdKEY = KeyFactory.createKey("c2dmreg","cr");
            Key serverTokenKEY = KeyFactory.createKey("vToken", "tokenkn");
            DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
            String appRegId = null, serverToken = null, chk =null;
            try {
                 appRegIdEntity = datastore.get(appRegIdKEY);
                 serverTokenEntity = datastore.get(serverTokenKEY);
                 serverToken = (String) serverTokenEntity.getProperty("token");
                 appRegId = (String) appRegIdEntity.getProperty("c2dmid");
    
    
                 RetCode = sendMessage(serverToken, appRegId, message);
    
            } catch (EntityNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
    
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                chk = "Entered In Exception";       
    
            }  
            resp.getWriter().println("Return code :" + RetCode + "chk value :" + chk);
        }
    
    
    
        //  Message Sending method
    
        public static int sendMessage(String auth_token, String registrationId, String message) throws IOException
        {
    
            StringBuilder postDataBuilder = new StringBuilder();
            postDataBuilder.append(PARAM_REGISTRATION_ID).append("=").append(registrationId);
            postDataBuilder.append("&").append(PARAM_COLLAPSE_KEY).append("=").append("0");
            postDataBuilder.append("&").append("data.payload").append("=").append(URLEncoder.encode(message, UTF8));
    
            byte[] postData = postDataBuilder.toString().getBytes(UTF8);
    
    
    
            URL url = new URL("https://android.clients.google.com/c2dm/send");
            //HttpsURLConnection.setDefaultHostnameVerifier(new CustomizedHostnameVerifier());//commented as was causing error, i dont know why
            HttpsURLConnection conn = (HttpsURLConnection) 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_token);
    
            OutputStream out = conn.getOutputStream();
            out.write(postData);
            out.close();
    
            int responseCode = conn.getResponseCode();
            return responseCode;
        }
    
    
    }
    

    但是浏览器总是显示RetCode = 0和Chk值=“在异常中输入”,即它从不将消息发送到Android设备,而是始终输入异常。我无法弄清楚代码中有什么问题。
    请帮忙。 谢谢。

1 个答案:

答案 0 :(得分:0)

这就是我最终解决的问题,代码帮助: -

public class C2dmsender {
    public static String send(String regid, String appRegId, String mtype, String[] message) throws UnsupportedEncodingException
    {


        String serverToken = ""//give the sever token here;
    data.append("registration_id=" + appRegId);//appRegId is the C2DM id of the device in which you want to push

    // Collapse key is for grouping messages and only the last sent message
    // with the same key going to be sent to the phone when the phone is
    // ready to get the message if its not from the beginning
    data.append("&collapse_key=test");

    // Here is the message we sending, key1 can be changed to what you whant
    // or if you whant to send more then one you can do (i think, not tested
    // yet), Testing is the message here.
    data.append("&data.key1=");

    // If you whant the message to wait to the phone is not idle then set
    // this parameter
    // data.append("&delay_while_idle=1");

    byte[] postData = data.toString().getBytes("UTF-8");


    try {
        // Send data
        URL url = new URL("https://android.apis.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="
                + serverToken);

        OutputStream out = conn.getOutputStream();
        out.write(postData);
        out.close();

        Integer responseCode = conn.getResponseCode();
        if (responseCode.equals(503)) {
            // the server is temporarily unavailable

        } else {
            if (responseCode.equals(401)) {
                // AUTH_TOKEN used to validate the sender is invalid

            } else {
                if (responseCode.equals(200)) {

                    // Check for updated token header
                    String updatedAuthToken = conn
                            .getHeaderField("Update-Client-Auth");
                    if (updatedAuthToken != null) {
                        serverToken = updatedAuthToken;

                    }

                    String responseLine = new BufferedReader(
                            new InputStreamReader(conn.getInputStream()))
                            .readLine();


            }
        }
    } catch (Exception e) {

        }


    }

}