Android C2DM无法链接客户端和服务器

发布于 2025-01-03 03:38:53 字数 8349 浏览 1 评论 0原文

我已经提到了 Vogella Android C2DM 教程 并按如下方式实现客户端和服务器。

我在应用程序中使用 3 个 URL,其中 1 个在客户端,2 个在服务器中遇到问题。

应该有我创建的服务器地址来代替第一个 URL。但我不知道到底该放什么。

其余 2 个 URL(google 的子 URL)无法正常访问。

我通过用

//================================= 括起来来突出显示这 3 个 URL 的用法===========================================

并对它们进行编号。

请注意,我可以在客户端注册,但无法接收任何消息。

在服务器端,我获得了身份验证,但是当我尝试发送消息时,它给出了 UnknownHostException

我知道我对这个问题很不清楚,但在 Android C2DM 开发 方面我绝对是初学者。

任何帮助表示赞赏。

如果有的话建议改变。

客户端代码片段(C2DMRegistrationReceiver.java)

public void sendRegistrationIdToServer(String deviceId,
        String registrationId) {
    Log.d("C2DM", "Sending registration ID to my application server");
    HttpClient client = new DefaultHttpClient();
    HttpPost post;

  // 1.) ========================================================================
 post = new HttpPost("http://vogellac2dm.appspot.com/register");
  //=============================================================================
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
        // Get the deviceID
        nameValuePairs.add(new BasicNameValuePair("deviceid", deviceId));
        nameValuePairs.add(new BasicNameValuePair("registrationid",
                registrationId));

        post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
        HttpResponse response = client.execute(post);
        BufferedReader rd = new BufferedReader(new InputStreamReader(
                response.getEntity().getContent()));
}

服务器代码片段

public class ServerSimulator extends Activity {
    private SharedPreferences prefManager;
    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";

    // Registration is currently hardcoded
    private final static String YOUR_REGISTRATION_STRING = "APA91bFQut1tqA-nIL1ZaV0emnp4Rb0smwCkrMHcoYRXeYVtIebJgrzOHQj0h76qKRzd3bC_JO37uJ0NgTcFO87HS9V7YC-yOP774pm0toppTHFO7Zc_PAw";

    private SharedPreferences prefs;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        prefManager = PreferenceManager.getDefaultSharedPreferences(this);
    }

    public void getAuthentification(View view) {
        SharedPreferences prefs = PreferenceManager
                .getDefaultSharedPreferences(this);

        HttpClient client = new DefaultHttpClient();
  // 2.) ==========================================================================
        HttpPost post = new HttpPost(
                "https://www.google.com/accounts/ClientLogin");
  //==============================================================================

        try {

            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
            nameValuePairs.add(new BasicNameValuePair("Email", prefs.getString(
                    "user", "[email protected]")));
            nameValuePairs.add(new BasicNameValuePair("Passwd", prefs
                    .getString("password", "myPassword")));
            nameValuePairs.add(new BasicNameValuePair("accountType", "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("HttpResponse", line);
                if (line.startsWith("Auth=")) {
                    Editor edit = prefManager.edit();
                    edit.putString(AUTH, line.substring(5));
                    edit.commit();
                    String s = prefManager.getString(AUTH, "n/a");
                    Toast.makeText(this, s, Toast.LENGTH_LONG).show();
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sendMessage(View view) {
        try {
            Log.e("sendMessage", "Started");
            String auth_key = prefManager.getString(AUTH, "n/a");
            // Send a sync message to this Android device.
            StringBuilder postDataBuilder = new StringBuilder();
            postDataBuilder.append(PARAM_REGISTRATION_ID).append("=")
                    .append(YOUR_REGISTRATION_STRING);

            postDataBuilder.append("&").append(PARAM_COLLAPSE_KEY).append("=")
                    .append("0");

            postDataBuilder.append("&").append("data.payload").append("=")
                    .append(URLEncoder.encode("Lars war hier", UTF8));

            byte[] postData = postDataBuilder.toString().getBytes(UTF8);

            // Hit the dm URL.
  // 3.) ==========================================================================
            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("Response Code=", String.valueOf(responseCode));
            // Validate the response code
            // 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();

            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("Tag", "Successfully sent data message to device: "
                        + responseLine);
            }

            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);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

I have referred Vogella Tutorial for Android C2DM
and implemented client and server as follows.

I've problem with 3 URL's used in application, 1 in client and 2 in server.

In place of 1st URL, there should be server address which I have created. But I don't get what exactly to put there.

Rest of the 2 URL's(sub-URL of google) are not accessible appropriately.

I've highlighted those 3 URL usage by enclosing them with

//==========================================================================

and numbering them.

Note that I'm able to register at the client side but not able to receive any message.

And at server side, I get the authentication but when I try to send the message it gives UnknownHostException.

I know I'm quite unclear in this question but I'm absolute beginner when it comes to Android C2DM development.

Any help appreciated.

Suggest changes if any.

Client code snippet (C2DMRegistrationReceiver.java)

public void sendRegistrationIdToServer(String deviceId,
        String registrationId) {
    Log.d("C2DM", "Sending registration ID to my application server");
    HttpClient client = new DefaultHttpClient();
    HttpPost post;

  // 1.) ========================================================================
 post = new HttpPost("http://vogellac2dm.appspot.com/register");
  //=============================================================================
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
        // Get the deviceID
        nameValuePairs.add(new BasicNameValuePair("deviceid", deviceId));
        nameValuePairs.add(new BasicNameValuePair("registrationid",
                registrationId));

        post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
        HttpResponse response = client.execute(post);
        BufferedReader rd = new BufferedReader(new InputStreamReader(
                response.getEntity().getContent()));
}

Server code snippet

public class ServerSimulator extends Activity {
    private SharedPreferences prefManager;
    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";

    // Registration is currently hardcoded
    private final static String YOUR_REGISTRATION_STRING = "APA91bFQut1tqA-nIL1ZaV0emnp4Rb0smwCkrMHcoYRXeYVtIebJgrzOHQj0h76qKRzd3bC_JO37uJ0NgTcFO87HS9V7YC-yOP774pm0toppTHFO7Zc_PAw";

    private SharedPreferences prefs;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        prefManager = PreferenceManager.getDefaultSharedPreferences(this);
    }

    public void getAuthentification(View view) {
        SharedPreferences prefs = PreferenceManager
                .getDefaultSharedPreferences(this);

        HttpClient client = new DefaultHttpClient();
  // 2.) ==========================================================================
        HttpPost post = new HttpPost(
                "https://www.google.com/accounts/ClientLogin");
  //==============================================================================

        try {

            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
            nameValuePairs.add(new BasicNameValuePair("Email", prefs.getString(
                    "user", "[email protected]")));
            nameValuePairs.add(new BasicNameValuePair("Passwd", prefs
                    .getString("password", "myPassword")));
            nameValuePairs.add(new BasicNameValuePair("accountType", "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("HttpResponse", line);
                if (line.startsWith("Auth=")) {
                    Editor edit = prefManager.edit();
                    edit.putString(AUTH, line.substring(5));
                    edit.commit();
                    String s = prefManager.getString(AUTH, "n/a");
                    Toast.makeText(this, s, Toast.LENGTH_LONG).show();
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sendMessage(View view) {
        try {
            Log.e("sendMessage", "Started");
            String auth_key = prefManager.getString(AUTH, "n/a");
            // Send a sync message to this Android device.
            StringBuilder postDataBuilder = new StringBuilder();
            postDataBuilder.append(PARAM_REGISTRATION_ID).append("=")
                    .append(YOUR_REGISTRATION_STRING);

            postDataBuilder.append("&").append(PARAM_COLLAPSE_KEY).append("=")
                    .append("0");

            postDataBuilder.append("&").append("data.payload").append("=")
                    .append(URLEncoder.encode("Lars war hier", UTF8));

            byte[] postData = postDataBuilder.toString().getBytes(UTF8);

            // Hit the dm URL.
  // 3.) ==========================================================================
            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("Response Code=", String.valueOf(responseCode));
            // Validate the response code
            // 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();

            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("Tag", "Successfully sent data message to device: "
                        + responseLine);
            }

            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);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

北座城市 2025-01-10 03:38:53

对于 URL 1,您需要在服务器上实现某种数据存储,该数据存储可以接收来自注册手机的请求并存储其注册 ID,以便您稍后可以向它们发送 c2dm 通知。就我而言,我使用了 apache2 服务器,它通过 https 接受 xml。

对于 URL 2,听起来您已经可以正常工作了,因为您说“在服务器端,我获得了身份验证”。您到底想在这里寻找什么?

对于网址 3,您应该使用 https://android.apis.google.com/c2dm/send 根据google c2dm 文档。虽然你使用的地址对我来说是解析。请注意,谷歌用于上述网址的 ssl 证书是错误的,并且无法正确验证,因此如果您尝试安全地发送通知,则可能会遇到这种情况。测试时您的模拟器/手机是否可以访问互联网?我不确定为什么您会收到该网址的 UnknownHost 异常。

For URL 1, you need to implement some kind of datastore on a server somewhere that can take requests from registered handsets and store their registration ids so you can later send c2dm notifications to them. In my case, I used an apache2 server that accepts xml over https.

For URL 2, it kind of sounds like you already got that working, since you say "And at server side, I get the authentication". What exactly are you looking for here?

For URL 3, you should be using https://android.apis.google.com/c2dm/send according to the google c2dm docs. Although the address you used resolves for me. Note that the ssl cert google uses for the url above is wrong and won't properly validate, so you may run into that if you're trying to securely send notifications. Did your emulator/handset have internet access when you tested? I'm not sure why else you'd get an UnknownHost exception for that url.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文