40

GCMと統合する小さなプロジェクトに取り組んでいるときに、少し奇妙な問題に遭遇しました。

メッセージが受信されたかどうかを確認するためにログを監視し始めると、ネットワークの状態を変更するまでメッセージが届かないように見えることがあります(つまり、元々WiFiで、WiFiをオフにしてモバイルデータに移動すると、メッセージが到着します大丈夫)。ネットワークの状態を変更した後、メッセージは完全に正常に到着し始めます。ネットワークの状態を以前の状態(この場合はWiFi)に戻すと、メッセージは引き続き受信されます。

プロジェクト自体には、起動時に開始する機能(起動時にGCMBaseIntentServiceを開始する)が含まれています。これも完全に正常に機能します。この問題が発生したときに手動でアプリを起動したので、アプリ/サービスは実行されていると確信しています(また、サービスが実行されているかどうかを確認し、実行されていない場合は実行して、登録されているかどうかを確認します)。

他の誰かがこの問題に遭遇したことがありますか、または私がこれをどのように解決できるかについての指針がありますか?メッセージが受信されていない時間と受信されている時間(ネットワークの状態を変更した後)の間のログには、あまり役に立ちません。GCMのドキュメントを確認しましたが、(デバイス自体の)タイムアウトが原因で受信されなかったメッセージや、これに影響を与える可能性のある構成オプションについての言及がありません。

支援に感謝します-android-sdkで提供されるデモアプリからほとんど逸脱していませんが、必要に応じてソースを提供できます。

4

5 に答える 5

39

私もこれに気付きました。私は実際のコードを掘り下げていませんが、これがなぜ起こるのかについての私の理解は次のとおりです。

GCM (およびほとんどのプッシュ メッセージング サービス) は、Google のプッシュ通知サーバーに対して有効なソケットを開いたままにしておくことで機能します。電話とサーバーの間で「ハートビート」メッセージを送信することにより、ソケットは開いたままになります。

場合によっては、ネットワークの状態が変化し、このソケットが壊れることがあります (たとえば、デバイスの IP アドレスが 3g から wifi に変わるため)。ソケットが再確立される前にメッセージが着信した場合、デバイスはメッセージをすぐには取得しません。

再接続は、電話機がソケットが壊れていることに気付いた場合にのみ発生します。これは、ハートビート メッセージを送信しようとしたときにのみ発生します。

繰り返しますが、それがどのように機能し、なぜそれが起こるのかについての私の基本的な理解であり、間違っている可能性があります.

于 2013-02-13T18:49:28.693 に答える
1

上記の回答のコメントによると、GCM プッシュ通知に関する私の経験によれば、ネットワーク (インターネット接続) が利用可能な場合、プッシュ通知を受信して​​はならない理由はありません。プッシュ通知用のアプリケーションを実行する前に、インターネット接続の可用性を常に確認します。このようにこれをチェックしてみてくださいこれが本当ならプッシュ通知を受け取るはずです

    private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager 
          = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null;
}
于 2013-02-12T16:44:23.987 に答える
-4

GCMIntentSeviceクラスでは、サーバーからメッセージを受信すると、onMessageメソッドが呼び出されるため、その時点で次のようなことができます...

PowerManager pm = (PowerManager) getApplicationContext()
                .getSystemService(Context.POWER_SERVICE);
        WakeLock wakeLock = pm.newWakeLock(
                        (PowerManager.SCREEN_BRIGHT_WAKE_LOCK
                                | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP),"TAG");
        wakeLock.acquire();

追加する必要があります

<uses-permission android:name="android.permission.WAKE_LOCK" /> マニフェストファイルの権限。

これでうまくいくはずです...

于 2013-02-09T08:43:56.017 に答える