1

我已经在服务器端和客户端成功地部署了 GCM 示例应用程序。我能够成功注册设备。但是当我尝试向设备发送消息时,服务器日志上显示以下异常:

Exception in thread "pool-1-thread-1" java.lang.IllegalArgumentException: argume
nt cannot be null
        at com.google.android.gcm.server.Sender.nonNull(Sender.java:553)
        at com.google.android.gcm.server.Sender.getString(Sender.java:534)
        at com.google.android.gcm.server.Sender.sendNoRetry(Sender.java:365)
        at com.google.android.gcm.server.Sender.send(Sender.java:261)
        at com.google.android.gcm.demo.server.SendAllMessagesServlet$1.run(SendA
llMessagesServlet.java:119)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExec
utor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor
.java:908)
        at java.lang.Thread.run(Thread.java:662)
Exception in thread "pool-1-thread-2" java.lang.IllegalArgumentException: argume
nt cannot be null
        at com.google.android.gcm.server.Sender.nonNull(Sender.java:553)
        at com.google.android.gcm.server.Sender.getString(Sender.java:534)
        at com.google.android.gcm.server.Sender.sendNoRetry(Sender.java:365)
        at com.google.android.gcm.server.Sender.send(Sender.java:261)
        at com.google.android.gcm.demo.server.SendAllMessagesServlet$1.run(SendA
llMessagesServlet.java:119)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExec
utor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor
.java:908)
        at java.lang.Thread.run(Thread.java:662)

在浏览器上,

显示以下消息,但由于异常,设备没有收到任何消息。

异步发送 1 个多播消息到 2 个设备

任何提示/建议都会有所帮助。

4

2 回答 2

3

我得到了完全相同的错误。查看 Sender.java 的源代码,这似乎发生在 Sender 试图通过 HttpURLConnection.getErrorStream() 找出错误的性质时。

if (status != 200) {
  // Exception on the line below due to getErrorStream() returning null
  responseBody = getString(conn.getErrorStream()); 
  logger.finest("JSON error response: " + responseBody);
  throw new InvalidRequestException(status, responseBody);
}

在我的情况下,由于 gcm 服务器返回 401 而触发了错误(我忘记了我是通过 VPN 工作的,并且没有在我的 Google API 帐户上将该 IP 列入白名单)。

您可能会从服务器获得非 200 状态。尝试通过以下方式查看问题所在:

$ curl -D headers.txt --header "Authorization: key=$api_key" --header Content-Type:"application/json" https://android.googleapis.com/gcm/send  -d "{\"registration_ids\":[\"$registrationID\"]}" && cat headers.txt

其中 $api_key 是您的 apiKey,$registrationID 是目标注册 ID。

发件人没有正确处理这个事实是一个不同的问题,但我不确定它是否与 gcm 库尝试读取错误的方式有关,或者它是否与 jdk 有问题..(此处为 1.6 )。鉴于 GCM 文档明确提到了这种情况,这很奇怪。

根据文档,getErrorStream()将返回 null:

如果没有错误,则连接未连接或服务器未发送有用数据。

  • 我们知道有一个错误(状态代码!= 200 已检查)
  • 我们知道有一个连接(在我的情况下返回了 401)
  • 我们知道服务器发送有用的数据:

来自未经授权的 ip:

[carlos@bad-box ~]$ curl -D headers.txt --header "Authorization: key=$api_key" --header Content-Type:"application/json" https://android.googleapis.com/gcm/send  -d "{\"registration_ids\":[\"$registrationID\"]}" && cat headers.txt

<HTML>
<HEAD>
<TITLE>Unauthorized</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Unauthorized</H1>
<H2>Error 401</H2>
</BODY>
</HTML>
HTTP/1.1 401 Unauthorized
Content-Type: text/html; charset=UTF-8
Date: Tue, 14 Aug 2012 00:30:47 GMT
Expires: Tue, 14 Aug 2012 00:30:47 GMT
Cache-Control: private, max-age=0
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Transfer-Encoding: chunked

编辑: 这现在已作为 GCM 项目的问题输入:http ://code.google.com/p/gcm/issues/detail?id=7

编辑: 该问题已得到修复,应该可以在 gcm.jar 助手类的下一个版本中使用。

于 2012-08-14T00:45:37.270 回答
0

发件人的参数不能为空。如果您将 null 作为参数传递给发件人,请检查日志。例如,如果您有类似的东西:

Sender sender = new Sender(businessLayer.Helper.getAndroidAPIkey());

如果由于某种原因businessLayer.Helper.getAndroidAPIkey()为 null,您将收到此异常。

于 2012-08-14T08:10:12.297 回答