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 です。

Sender がこれを正しく処理しないという事実は別の問題ですが、gcm ライブラリがエラーを読み取ろうとしている方法に関連しているのか、それとも jdk の問題なのかはわかりません.. (1.6 here )。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

Sender への引数は null であってはなりません。Sender への引数として null を渡している場合は、ログを確認してください。たとえば、次のようなものがある場合:

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

何らかの理由businessLayer.Helper.getAndroidAPIkey()で null の場合、この例外が発生します。

于 2012-08-14T08:10:12.297 に答える