it-swarm.com.de

So beheben Sie den Google Cloud Messaging-Registrierungsfehler: SERVICE_NOT_AVAILABLE?

Ich bin auf ein seltsames Problem gestoßen - Ich habe GCM schon lange in meiner Anwendung verwendet und alles funktioniert perfekt. Vor einer Veröffentlichung bei Google Play habe ich jedoch den Namen des Anwendungspakets von com.Android.testapp in com.Android.recognition geändert, und nachdem dieser GCM nicht mehr funktioniert. Zuerst bekam ich den Fehler GCM sender id not set on constructor und habe ihn durch Überschreiben von getSenderIds(Context context) behoben, aber jetzt kann ich keine Registrierungs-ID erhalten. Hier sind die Meldungen von logcat: enter image description here

Wie kann ich das beheben? Als ich zu einem neuen Paket wechselte, änderte ich alles in der Manifestdatei in das neue Paket:

<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>

Was ist also das Problem dahinter? Kann das Umbenennen des Anwendungspakets dazu führen oder gibt es einen anderen Grund?

24

Dieser SERVICE_NOT_AVAILABLE-Fehler besagt, dass GCM Service nicht aktuell verfügbar ist. Warten Sie und versuchen Sie es nach einiger Zeit. 

Dies passiert oft (wie meine Erfahrung), also machen Sie sich keine Sorgen. 


Siehe die GCMConstants-Klasse von GCM Lib. 

/**
     * 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";

Für weitere Untersuchungen siehe handleRegistration() von GCMBaseIntentService 

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);
        }
    }
30
Pankaj Kumar

Das Problem ist beantwortet, in meinem Fall war es etwas komplizierter.

  1. Überprüfen Sie, ob Sie eine aktive Internetverbindung haben
  2. Stellen Sie sicher, dass Sie in Ihrem Manifest über eine Internet-Berechtigung verfügen
  3. Stellen Sie sicher, dass der Paketname korrekt ist, wie Eran erwähnt hat
  4. Die Gerätezeit ist korrekt eingestellt. Selbst wenn alles perfekt ist, schlägt die Geräteuhr fehl, wenn die Uhr nicht richtig eingestellt ist.

Falsche Uhr hat zu Problemen geführt. :)

42
Aman Gautam

Stellen Sie sicher, dass Sie den Paketnamen im Berechtigungsteil Ihres Manifests geändert haben:

<permission Android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE"
    Android:protectionLevel="signature" />
<uses-permission Android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE" />

Ich hatte einen ähnlichen Fehler aufgrund eines falschen Paketnamens in diesem Teil.

18
Eran

SERVICE_NOT_AVAILABLE ist eines der frustrierendsten Probleme mit Google Cloud Messaging. Dies ist eine Ausnahme von GoogleCloudMessaging.register(SENDER_ID), dem Funktionsaufruf, der das Gerät für Push-Benachrichtigungen registriert und eine Registrierungs-ID zurückgibt.

  1. SERVICE_NOT_AVAILABLE kann bedeuten, dass das Gerät des Benutzers die Antwort auf die Registrierungsanforderung nicht lesen kann oder dass ein Fehlercode 500/503 vom Server zurückgegeben wurde. Entwickler haben keine Möglichkeit, diesen Fehler zu beheben, da sie sich am Ende von Google befinden. Daher können wir blind vorschlagen, dass der Benutzer es in einigen Stunden erneut versuchen sollte.
  2. SERVICE_NOT_AVAILABLE kann auf einigen Geräten auftreten, obwohl die Registrierung erfolgreich war. Dies kann durch Implementierung eines Workaround-Broadcast-Empfängers behoben werden, der das Token abfängt, wenn der Anruf fehlschlägt. Ich habe diese Problemumgehung implementiert. Möglicherweise wurde das Problem für einige Benutzer behoben, aber ich erhielt noch viele andere Beschwerden von SERVICE_NOT_AVAILABLE.
  3. SERVICE_NOT_AVAILABLE kann aufgrund einer veralteten oder fehlenden Google Play Services-Bibliothek auf dem Gerät auftreten. In diesem Fall könnte die App den Benutzer theoretisch dazu auffordern, die Google Play-Dienste zu aktualisieren, indem der entsprechende Eintrag der Google Play-App geöffnet wird. Die App hat jedoch keine Ahnung, dass SERVICE_NOT_AVAILABLE aus diesem Grund ausgelöst wurde, sodass der Benutzer nicht blind auf die Google Play Services-App-Seite von Google Play umgeleitet werden kann.
  4. SERVICE_NOT_AVAILABLE kann auftreten, wenn die Uhr des Geräts nicht mit dem Netzwerk synchronisiert ist. Entwickler haben auch hier keine Möglichkeit zu wissen, dass dies das genaue Problem ist. Daher können wir dem Benutzer blindlings vorschlagen, die Synchronisierung der Systemuhr zu überprüfen, in der Hoffnung, dass dies eine der wenigen ist, deren Uhren nicht synchronisiert sind.
  5. SERVICE_NOT_AVAILABLE kann auftreten, wenn ein gerooteter Benutzer die Hangouts/GTalk-App von ihrem Gerät gelöscht hat (weil er dies als Bloatware betrachtet). GCM wird von Hangouts/GTalk implementiert und gehandhabt. Daher ist die Verwendung von GCM nicht möglich.
  6. SERVICE_NOT_AVAILABLE kann auftreten, wenn der Benutzer ein Gerät ausführt, auf dem keine Google-APIs installiert sind (z. B. Amazon Kindle). Hier ist nichts zu tun, diese Benutzer werden niemals Push-Benachrichtigungen von Ihrer App erhalten.

Lesen Sie mehr: http://eladnava.com/google-cloud-messaging-extremely-unreliable/

Allein diese Probleme reichten aus, um nach GCM-Alternativen zu suchen. Ich bekomme alle ein bis zwei Tage eine 1-Sterne-Bewertung in meiner App. Ein Kommentar enthält die Fehlermeldung, wenn ein SERVICE_NOT_AVAILABLE ausgelöst wurde. Ich konnte diesen Benutzern nichts helfen, weil die Mehrheit sie aus Gründen erhielt, die außerhalb ihrer Kontrolle lagen.

Eine Alternative zu Google Cloud Messaging

Pushy ( https://pushy.me/ ) ist ein eigenständiges Push-Benachrichtigungs-Gateway, das völlig unabhängig von GCM ist. Es unterhält eine eigene Hintergrund-Socket-Verbindung, genau wie GCM, um Push-Benachrichtigungen zu erhalten. Das zugrunde liegende Protokoll ist MQTT, ein extrem leichtes Pub/Sub-Protokoll, das sehr wenig Netzwerkbandbreite und Batterie benötigt.

Ein großer Vorteil von Pushy ist, dass der Code zum Senden einer Push-Benachrichtigung (vom Server) und zum Registrieren des Geräts für Push-Benachrichtigungen tatsächlich zwischen GCM und Pushy austauschbar ist. Dies macht es sehr einfach, zu Pushy zu wechseln, nachdem GCM implementiert wurde und es wegen seiner Instabilität aufgegeben werden muss.

(Vollständige Offenlegung: Ich habe Pushy für meine eigenen Projekte gegründet und habe erkannt, dass viele Apps von einem solchen Service profitieren würden.)

17
Elad Nava

Für mich war die Gerätezeit nicht korrekt. Ich habe die Geräteeinstellungen geändert, um "Automatisches Datum und Uhrzeit" zu verwenden, es erneut versucht und alles in Ordnung.

Prost

13
Mahendra Liya

Ich hatte das gleiche Problem, aber keine der oben genannten Lösungen löste das Problem in meinem Fall. Glücklicherweise habe ich es vor kurzem gelöst und möchte erklären, wie es hilft, anderen zu helfen:

In meinem Fall habe ich den Push-Dienst in einer benutzerdefinierten Anwendungsklasse registriert (die vor jeder Aktivität ausgeführt wird, und ich denke, das liegt daran, dass einige Dinge nicht eigens initialisiert wurden). Durch die Änderung zur Hauptaktivität wurde das Problem behoben.

public class MyCustomApp extends Application {

    @Override
    public void onCreate() {
         super.onCreate();
         PushService.register(this); //BAD IDEA, don't register pushes in Application Class
    }

}
3
Corbella

Bei mir gab es Verbindungsprobleme. Internetverbindung ändern löste mein Problem

3

Ich hatte ein ähnliches Problem. Funktionierte gut auf einem Google Nexus (Android 4.4.2), aber nicht auf einer Samsung Galaxy S3 (Android 4.1.2) . Ich erhielt SERVICE_NOT_AVAILABLE bei der Registrierung des Samsung. Es stellte sich heraus, dass die Zeit für Samsung abgelaufen war. Es wurde nicht für die automatische Aktualisierung mit Netzwerkzeit eingestellt. Nachdem ich das GCM behoben hatte, funktionierte es wie ein Zauber. Danke - Umesh

3
user3541251

In meinem Fall bestand die Lösung darin, dem Manifest eine neue Absichtsfilteraktion (REGISTRATION) hinzuzufügen. Per https://snowdog.co/blog/dealing-with-service_not_available-google-cloud-messaging/

    <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>

Ich muss zugeben, dass ich überrascht bin, dass dies funktioniert, da es im Tutorial fehlt, aber das Herausnehmen macht aus einer erfolgreichen Registrierungs-ID definitiv eine Ausnahme.

Hinweis: Verwenden des Emulators Nexus 5 API 21 (Lollipop).

3
Brian Marick

Für mich hatte ich den "Hintergrunddatenzugriff" für Google-Dienste deaktiviert, indem ich in meinem Galaxy S4 in der Option "Datennutzung" die Option "Hintergrunddaten einschränken" aktiviert hatte. Sobald ich es einschaltete, wurde das Problem im Kellernetzwerk behoben. Im WiFi funktionierte es gut.

3
ahmadalibaloch

Für mich bestand das Problem darin, dass das Telefon nicht mit dem Internet verbunden war. Ich trenne die Verbindung und verbinde mich mit dem WLAN, teste die Verbindung mit dem Browser und testete erneut. Lief wie am Schnürchen :-)

2

Für mich war das SERVICE_NOT_AVAILABLE Problem in meinem Anwendungsprojekt wegen der Empfängerklasse . Also löste ich nach der Implementierung des Empfängers das Folgende .<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>

0
Hay Thi

Ich hatte ein OnePlus2, das bei Daten keine Pushs empfangen konnte. Wenn ich mit logcat verbunden bin, habe ich eine Menge von diesem Fehler gesehen, bin mir aber nicht sicher, ob er damit zusammenhängt.

Ich gab den Versuch auf, eine entsprechende Einstellung zu finden, und setzte das Gerät einfach auf die Werkseinstellungen zurück. Bei OnePlus-Geräten, auf denen OxygenOS ausgeführt wird, treten bei der Installation von Softwareupdates manchmal seltsame Konfigurationsfehler auf. Durch das Zurücksetzen auf die Werkseinstellungen und das Wiederherstellen von Google Backup werden die Dinge schneller als erwartet ausgeführt, um das zugrunde liegende Problem zu verstehen (und der Benutzer kann dies nicht einmal tun den richtigen Zugriff, um das zugrunde liegende Problem zu beheben).

0
binki

Ich hatte "Background Data Access" für Google-Dienste deaktiviert. Durch Deaktivieren der Option "Hintergrunddaten einschränken" in der Option zur Datennutzung funktioniert es für mich!

0
Gowtham Venkat

Für mich hat goolge meine IP gesperrt !! Ich musste meinen DSL-Anschluss zurücksetzen, um eine neue IP-Adresse aus dem Pool zu erhalten, und alles funktionierte wieder. Jedenfalls funktioniert es jetzt, ich hoffe, das hilft jemand anderem :)

0
D.Snap