私は奇妙な問題に遭遇しました-私はかなり長い間アプリケーションでGCMを使用しており、すべてが完全に機能しています。ただし、Google Playのリリース前に、アプリケーションパッケージ名を_com.Android.testapp
_から_com.Android.recognition
_に変更し、このGCMが機能しなくなった後。最初にエラー_GCM sender id not set on constructor
_が発生し、getSenderIds(Context context)
をオーバーライドして修正しましたが、登録IDを取得できなくなりました。 logcatからのメッセージは次のとおりです。
どうすれば修正できますか?新しいパッケージに切り替えたときに、マニフェストファイルのすべてを新しいパッケージに変更しました。
_<receiver
Android:name="com.google.Android.gcm.GCMBroadcastReceiver"
Android:permission="com.google.Android.c2dm.permission.SEND" >
<intent-filter>
<action Android:name="com.google.Android.c2dm.intent.RECEIVE" />
<action Android:name="com.google.Android.c2dm.intent.REGISTRATION" />
<category Android:name="com.Android.recognition" />
</intent-filter>
</receiver>
_
それで、この背後にある問題は何ですか?アプリケーションパッケージの名前を変更するとこれが発生する可能性がありますか、それとも別の理由がありますか?
この_SERVICE_NOT_AVAILABLE
_エラーは、_GCM Service
_が現在使用できないことを示しています。しばらく待ってから試してください。
これは(私の経験として)何度も発生するので、心配する必要はありません。
GCM LibのGCMConstants
クラスを参照してください。
_/**
* The device can't read the response, or there was a 500/503 from the
* server that can be retried later. The application should use exponential
* back off and retry.
*/
public static final String ERROR_SERVICE_NOT_AVAILABLE =
"SERVICE_NOT_AVAILABLE";
_
詳細な調査については、GCMBaseIntentService
のhandleRegistration()
を参照してください。
_private void handleRegistration(final Context context, Intent intent) {
String registrationId = intent.getStringExtra(EXTRA_REGISTRATION_ID);
String error = intent.getStringExtra(EXTRA_ERROR);
String unregistered = intent.getStringExtra(EXTRA_UNREGISTERED);
Log.d(TAG, "handleRegistration: registrationId = " + registrationId +
", error = " + error + ", unregistered = " + unregistered);
// registration succeeded
if (registrationId != null) {
GCMRegistrar.resetBackoff(context);
GCMRegistrar.setRegistrationId(context, registrationId);
onRegistered(context, registrationId);
return;
}
// unregistration succeeded
if (unregistered != null) {
// Remember we are unregistered
GCMRegistrar.resetBackoff(context);
String oldRegistrationId =
GCMRegistrar.clearRegistrationId(context);
onUnregistered(context, oldRegistrationId);
return;
}
// last operation (registration or unregistration) returned an error;
Log.d(TAG, "Registration error: " + error);
// Registration failed
if (ERROR_SERVICE_NOT_AVAILABLE.equals(error)) {
boolean retry = onRecoverableError(context, error);
if (retry) {
int backoffTimeMs = GCMRegistrar.getBackoff(context);
int nextAttempt = backoffTimeMs / 2 +
sRandom.nextInt(backoffTimeMs);
Log.d(TAG, "Scheduling registration retry, backoff = " +
nextAttempt + " (" + backoffTimeMs + ")");
Intent retryIntent =
new Intent(INTENT_FROM_GCM_LIBRARY_RETRY);
retryIntent.putExtra(EXTRA_TOKEN, TOKEN);
PendingIntent retryPendingIntent = PendingIntent
.getBroadcast(context, 0, retryIntent, 0);
AlarmManager am = (AlarmManager)
context.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + nextAttempt,
retryPendingIntent);
// Next retry should wait longer.
if (backoffTimeMs < MAX_BACKOFF_MS) {
GCMRegistrar.setBackoff(context, backoffTimeMs * 2);
}
} else {
Log.d(TAG, "Not retrying failed operation");
}
} else {
// Unrecoverable error, notify app
onError(context, error);
}
}
_
私の場合、問題はもう少し複雑でした。
間違った時計が問題を引き起こしました。 :)
マニフェストの権限の部分でパッケージ名を変更したことを確認してください:
<permission Android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE"
Android:protectionLevel="signature" />
<uses-permission Android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE" />
その部分のパッケージ名が正しくないため、同様のエラーが発生しました。
SERVICE_NOT_AVAILABLEは、Google Cloud Messagingで最もイライラする問題の1つです。これは、プッシュ通知用にデバイスを登録し、登録IDを返す関数呼び出しであるGoogleCloudMessaging.register(SENDER_ID)
によってスローされる例外です。
詳細: http://eladnava.com/google-cloud-messaging-extremely-unreliable/
これらの問題だけで、GCMの代替案を探し始めることができました。 SERVICE_NOT_AVAILABLEがスローされたときに表示されるエラーメッセージを含むコメントを付けて、アプリで1つまたは2つ星のレビューを毎日取得します。これらのユーザーを支援するために私ができることは何もありませんでした。なぜなら、彼らの大半は、彼らの制御不能の理由でそれを受け取っていたからです。
Googleクラウドメッセージングの代替
Pushy( https://pushy.me/ )は、GCMから完全に独立したスタンドアロンのプッシュ通知ゲートウェイです。プッシュ通知を受信するために、GCMと同様に独自のバックグラウンドソケット接続を維持します。基礎となるプロトコルは、ネットワーク帯域幅とバッテリーをほとんど使用しない、非常に軽量なpub/subプロトコルであるMQTTです。
Pushyの大きな利点は、(サーバーから)プッシュ通知を送信し、プッシュ通知用にデバイスを登録するためのコードが、実際にはGCMとPushyの間で交換可能であることです。これにより、GCMを実装し、不安定性のためにそれを捨てなければならない後、Pushyに切り替えるのは非常に簡単になります。
(完全開示:自分のプロジェクトのためにPushyを設立し、多くのアプリがそのようなサービスから利益を得ることに気付きました)
私にとって-デバイスの時刻は正しくありませんでした。 「自動日付と時刻」を使用するようにデバイス設定を変更し、再試行しましたが、すべてうまくいきました。
乾杯
私は同じ問題を抱えていましたが、上記の解決策のいずれも私の場合の問題を解決しませんでした。幸いなことに、私は最近それを解決したので、他の人に役立つ方法を説明したいと思います。
私の場合、Pushサービスをカスタムアプリケーションクラスに登録していました(これはアクティビティの前に実行されます。これは、何らかの理由で適切に初期化されなかったためだと思います)。メインアクティビティに変更することで問題は解決しました。
public class MyCustomApp extends Application {
@Override
public void onCreate() {
super.onCreate();
PushService.register(this); //BAD IDEA, don't register pushes in Application Class
}
}
私には接続の問題がありました。インターネット接続を変更すると問題が解決しました
同様の問題がありました。 google nexus(Android 4.4.2)では正常に動作しましたが、Samsung galaxy s3(Android 4.1.2)では正常に動作しました。 Samsungへの登録時にSERVICE_NOT_AVAILABLEを取得していました。それはサムスンの時間がオフになったことが判明した。 Network Timeで自動更新するように設定されていません。 GCMが魅力のように機能することを修正したら。ありがとう-ウメシュ
<receiver
Android:name=".RemoteNotificationReceiver"
Android:permission="com.getset.getset.c2dm.permission.SEND" >
<intent-filter>
<action Android:name="com.getset.getset.c2dm.intent.RECEIVE" />
<action Android:name="com.getset.getset.c2dm.intent.REGISTRATION" />
<category Android:name="com.getset.getset" />
</intent-filter>
</receiver>
チュートリアルから欠落していることを考えると、これが機能することに驚いていることを認めざるを得ませんが、それを削除することは間違いなく成功した登録IDを例外に変えます。
注:Nexus 5 API 21(Lollipop)エミュレーターを使用します。
私にとっては、Galaxy S4の[データ使用オプション]で[バックグラウンドデータを制限する]をオンにして、Googleサービスの[バックグラウンドデータアクセス]を無効にしました。セラーネットワークで問題を解決するとすぐに解決しました。 Wifiでは正常に動作していました。
私にとって問題は、電話がインターネットに接続されていないことでした。 Wi-Fiを切断して接続し、ブラウザとの接続をテストして、再度テストしました。魅力のように働いた:-)
私にとって、SERVICE_NOT_AVAILABLEの問題は、レシーバクラスのために私のアプリケーションプロジェクトにありました。そこで、以下のように受信機を実装して解決しました。 <receiver Android:name="receiver name" Android:permission="com.google.Android.c2dm.permission.SEND"> <intent-filter> <action Android:name="com.google.Android.c2dm.intent.RECEIVE"/> <action Android:name="com.google.Android.c2dm.intent.REGISTRATION"/> <category Android:name="your package"/> </intent-filter> </receiver>
それがあなたの助けになることを願っています:-)。
データがあるときにプッシュを受信できないOnePlus2がありました。 logcat
と接続したときに、このエラーの多くを見ましたが、関連しているかどうかはわかりません。
私はそれに対応する設定を見つけることをあきらめ、デバイスを工場出荷時の状態にリセットしました。 OxygenOSを実行しているOnePlusデバイスは、ソフトウェアの更新をインストールするときに奇妙な構成エラーを受け取り、工場出荷時の状態にリセットしてからGoogleバックアップから復元すると、根本的な問題を理解するのにかかるよりも速く動作します(そして、ユーザーが根本的な問題を修正するための適切なアクセス権)。
Googleサービスの「バックグラウンドデータアクセス」を有効にしていました。 [データ使用オプション]の[バックグラウンドデータを制限する]のチェックを外すことで動作します。
私にとっては、goolgeは私のIPをブロックしました!プールから新しいIPを取得するためにDSL接続をリセットする必要がありましたが、すべてが再び機能しました。とにかく今は働いています、私はこれが誰か他の人を助けることを願っています:)