Android HttpsURLConnection и JSON для нового GCM

Я пересматриваю некоторые части своего приложения, чтобы использовать новую службу GCM для замены C2DM. Я просто хочу создать запрос JSON из программы Java для тестирования, а затем прочитать ответ. На данный момент я не могу найти НИКАКИХ проблем с форматированием моего запроса JSON, и сервер Google всегда возвращает код 400, что указывает на проблему с моим JSON. http://developer.android.com/guide/google/gcm/gcm.html#server

JSONObject obj = new JSONObject();
    obj.put("collapse_key", "collapse key");
    JSONObject data = new JSONObject();
    data.put("info1", "info_1");
    data.put("info2", "info 2");
    data.put("info3", "info_3");
    obj.put("data", data);
    JSONArray ids = new JSONArray();
    ids.add(REG_ID);
    obj.put("registration_ids", ids);
    System.out.println(obj.toJSONString());

Я печатаю свой запрос на консоль eclipse, чтобы проверить его форматирование.

byte[] postData = obj.toJSONString().getBytes();
    try{
    URL url = new URL("https://android.googleapis.com/gcm/send");
    HttpsURLConnection.setDefaultHostnameVerifier(new JServerHostnameVerifier());
    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    conn.setDoOutput(true);
    conn.setDoInput(true);
    conn.setUseCaches(false);

    conn.setRequestMethod("POST");
    conn.setRequestProperty("Content-Type", "application/json");

conn.setRequestProperty("Authorization", "key=" + API_KEY);
    System.out.println(conn.toString());
    OutputStream out = conn.getOutputStream();
              // exception thrown right here. no InputStream to get
    InputStream in = conn.getInputStream();
    byte[] response = null;
    out.write(postData);
    out.close();
    in.read(response);
    JSONParser parser = new JSONParser();
    String temp = new String(response);
    JSONObject temp1 = (JSONObject) parser.parse(temp);
    System.out.println(temp1.toJSONString());
    int responseCode = conn.getResponseCode();
     System.out.println(responseCode + "");
    } catch(Exception e){
        System.out.println("Exception thrown\n"+ e.getMessage());
    }


}

Я уверен, что мой ключ API правильный, так как это приведет к ошибке 401, как говорится в документации Google. Я впервые делаю JSON, но его легко понять из-за его простоты. У кого-нибудь есть идеи, почему я всегда получаю код 400?

обновление: я протестировал примеры классов сервера Google, предоставленные gcm, поэтому проблема ДОЛЖНА быть связана с моим кодом.

{"collapse_key":"new-test-notification","data":{"info1":"info_1","info3":"info_3","info2":"info 2"},"registration_ids":["APA91bG3bmCSltzQYl_yOcjG0LPcR1Qemwg7osYJxImpSuWZftmmIjUGH_CSDG3mswKuV3AAb8GSX7HChOKGAYHz1A_spJus5mXFtfOrK0fouBD7QBpKnfc_ly0t3S8vSYWRjuGxtXrt"]}

person Ryan Gray    schedule 29.06.2012    source источник
comment
когда у меня была эта проблема со старым C2DM, это означало, что я не был зарегистрирован в службе Google, в консоли разработчика проверьте: 1. вы создали проект в своей консоли? 2. Вы включили облачный сервис Google для своего проекта в консоли разработчика? 3. Я предполагаю, что у вас есть действительный ключ API.   -  person codeScriber    schedule 30.06.2012
comment
Можете ли вы опубликовать строку запроса JSON, просто распечатайте вывод temp1.toJSONString().   -  person azgolfer    schedule 01.07.2012
comment
Только что обновлено с помощью JSON String. Спасибо, проблема осталась   -  person Ryan Gray    schedule 03.07.2012
comment
Кстати, убедитесь, что вы делаете это в отдельном потоке :)   -  person Alex Lockwood    schedule 03.07.2012
comment
Я понимаю, что вы имеете в виду, но это не из моего приложения. Это проект Java, созданный для тестирования GCM. Нет необходимости в отдельных потоках   -  person Ryan Gray    schedule 03.07.2012
comment
@codeScriber Да, я сделал все это. ценю ответ   -  person Ryan Gray    schedule 03.07.2012
comment
@ Райан, как насчет того, чтобы распечатать тело ошибки, которое тебе прислал GCM? По их словам, 400 — это ошибка JSON, и дополнительная информация будет включена в ответное сообщение. Попробуйте распечатать conn.getInputStream() или conn.getErrorStream().   -  person azgolfer    schedule 04.07.2012


Ответы (3)


Я решил это, используя другой подход, поэтому, должно быть, это была моя первоначальная реализация.

List<NameValuePair> list = new ArrayList<NameValuePair>();
        list.add(new BasicNameValuePair("username",username));
        list.add(new BasicNameValuePair("deviceId",regId));
        list.add(new BasicNameValuePair("deviceType","AndroidPhone"));
        DefaultHttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost("example.url.com");
        post.setEntity(new UrlEncodedFormEntity(list));
        ResponseHandler<String> handler = new BasicResponseHandler();
        HttpResponse response = client.execute(post);
        String responseString = handler.handleResponse(response);
        JSONObject jsonResponse = new JSONObject(responseString);
person Ryan Gray    schedule 09.07.2012
comment
Что такое ответ в handler.handleResponse(response)? Это функция обратного вызова для обработки ответа сервера? Не могли бы вы опубликовать пример кода для этого? Спасибо - person CuriousCoder; 27.08.2012

Я читаю здесь, что вы должны использовать свой «Ключ для браузерных приложений» GCM с PHP ( Google Cloud Messaging) (в комментариях)

person Klaasvaak    schedule 03.07.2012
comment
В отличие от ключа для серверных приложений? я попробую - person Ryan Gray; 03.07.2012

Попробуйте воспроизвести ошибку с помощью curl или другого инструмента командной строки, чтобы мы могли исключить возможность того, что в вашем java есть ошибка, которую мы все упустили.

person Rob Starling    schedule 07.07.2012