Android C2DM не может связать клиент и сервер - PullRequest
0 голосов
/ 04 февраля 2012

Я сослался Учебник Vogella для Android C2DM и реализовал клиент и сервер следующим образом.

У меня проблема с 3 URL-адресами, используемыми в приложении, 1 на клиенте и 2 на сервере.

Вместо 1-го URL должен быть адрес сервера, который я создал. Но я не понимаю, что именно положить туда.

Остальные 2 URL-адреса (под-URL Google) не доступны надлежащим образом.

Я выделил использование этих трех URL, заключив их в

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

и нумерация их.

Обратите внимание, что я могу зарегистрироваться на стороне клиента, но не могу получать никаких сообщений.

И на стороне сервера я получаю аутентификацию, но когда я пытаюсь отправить сообщение, оно выдает UnknownHostException.

Я знаю, что совершенно неясен в этом вопросе, но я абсолютный новичок, когда дело доходит до Android C2DM development.

Любая помощь приветствуется.

Предложить изменения, если таковые имеются.

Фрагмент кода клиента (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", "myUserName@gmail.com")));
            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);
        }
    }
}

1 Ответ

1 голос
/ 04 февраля 2012

Для URL 1 вам необходимо внедрить какое-то хранилище данных на сервере, где он может принимать запросы от зарегистрированных мобильных телефонов и сохранять их регистрационные идентификаторы, чтобы впоследствии вы могли отправлять им уведомления c2dm. В моем случае я использовал сервер apache2, который принимает XML через https.

Для URL 2 это звучит так, как будто вы уже сработали, поскольку вы говорите: «А на стороне сервера я получаю аутентификацию». Что именно вы здесь ищете?

Для URL 3 вы должны использовать https://android.apis.google.com/c2dm/send в соответствии с документами Google C2DM . Хотя адрес, который вы использовали, разрешает мне. Обратите внимание, что ssl cert, который Google использует для указанного выше URL-адреса, неверен и не может быть правильно проверен, поэтому вы можете столкнуться с этим, если попытаетесь безопасно отправить уведомления. Был ли у вашего эмулятора / телефона доступ в интернет при тестировании? Я не уверен, почему иначе вы получите исключение UnknownHost для этого URL.

...