IOException 发送 GCM 通知

IOException sending GCM notifications

我正在尝试向 GCM 服务器发送一些 JSON 通知,但我收到了这个错误列表

Response Code: 400
java.io.IOException: Server returned HTTP response code: 400 for URL: https://gcm-http.googleapis.com/gcm/send
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
        at java.lang.reflect.Constructor.newInstance(Unknown Source)
        at sun.net.www.protocol.http.HttpURLConnection.run(Unknown Source)
        at sun.net.www.protocol.http.HttpURLConnection.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.net.www.protocol.http.HttpURLConnection.getChainedException(Unknown Source)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
        at controller.Notification.post(Notification.java:181)
        at controller.App.main(App.java:17)
Caused by: java.io.IOException: Server returned HTTP response code: 400 for URL: https://gcm-http.googleapis.com/gcm/send
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
        at java.net.HttpURLConnection.getResponseCode(Unknown Source)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
        at controller.Notification.post(Notification.java:179)
        ... 1 more

奇怪的是,只有当我尝试发送到单个设备时才会发生这种情况。如果我尝试使用 registration_id 字段发送到多个设备,它会起作用。参考资料说错误 400 意味着 JSON 无法解析,但我尝试将其打印出来并且看起来不错:

组播发送:(响应码:200,注册无效)

{"registration_ids":["asdlfiwuhfs"]}

发送到单个设备:(响应代码:400,以上错误)

{"to":"asdlfiwuhfs"}

发送到单个或多个设备的功能只有一条不同的线路。其中一个添加了 to 字段,另一个添加了 registration_id 字段。

obj.put("registration_ids", regIds); // multiple devices
obj.put("to", regId);                // single device

可能是什么问题?

编辑:

下面第三行是错误中提到的第181行:

int responseCode = conn.getResponseCode();
System.out.println("Response Code: " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); // 181

我在 github 上的 this code 找到了解决方案。

似乎getInputStream()只有在响应代码为200时才使用。否则,应使用 getErrorStream()

所以将我的代码改成这个修复了它。

int responseCode = conn.getResponseCode();
System.out.println("Response Code: " + responseCode);

BufferedReader in = null;
if (responseCode == 200)
    in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
else
    in = new BufferedReader(new InputStreamReader(conn.getErrorStream()));