2013-06-19 28 views
24

Ho riscontrato uno strano problema: utilizzo GCM nella mia applicazione da parecchio tempo e tutto funziona perfettamente. Tuttavia, prima di passare a Google Play ho cambiato il nome del mio pacchetto di applicazioni da com.android.testapp a com.android.recognition e dopo questo GCM ha smesso di funzionare. All'inizio ho ricevuto l'errore GCM sender id not set on constructor e l'ho risolto sostituendo getSenderIds(Context context), ma ora non riesco a ottenere un ID di registrazione. Ecco i messaggi da logcat: enter image description hereCome risolvere l'errore di registrazione di Google Cloud Messaging: SERVICE_NOT_AVAILABLE?

Come posso risolvere questo? Quando sono passato a un nuovo pacchetto ho cambiato tutto nel file manifesto per il nuovo pacchetto:

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

Allora, qual è il problema alla base di questo? La ridenominazione del pacchetto dell'applicazione può causare questo o esiste un altro motivo?

+0

Stai lavorando all'emulatore? Quale emulatore? –

+0

@PankajKumar Sto lavorando su dispositivi reali: Kindle Fire e LG NEXUS 4. E niente funziona – MainstreamDeveloper00

+0

Per me, sembro strano. Devo provare un paio di volte. A volte, ho bisogno di forzare la chiusura dell'app. Quindi funziona. –

risposta

30

Questo errore SERVICE_NOT_AVAILABLE indica che GCM Service non è disponibile nella corrente. Aspetta e prova dopo un po 'di tempo.

Questo accade molte volte (come la mia esperienza), quindi non preoccuparti.


Vedere la classe GCMConstants di 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"; 

Per ulteriori indagini vedere handleRegistration() di 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); 
     } 
    } 
+3

"Aspetta e prova dopo un po '." Ho già questo errore per tre giorni su diversi dispositivi – MainstreamDeveloper00

+2

Non ho affrontato questo problema più di 1 giorno. Se stai affrontando questo problema per 3 giorni, potrebbe esserci qualche altro problema. Hai avuto successo sullo stesso codice in anteprima? –

+0

"Uso GCM nella mia applicazione da parecchio tempo e tutto funziona perfettamente" Ho scritto a riguardo nella mia domanda – MainstreamDeveloper00

18

Assicurarsi che è stato modificato il nome del pacchetto nella parte permessi del vostro manifesto:

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

Ho avuto un errore simile a causa a un nome di pacchetto errato in quella parte.

+0

Non è sufficiente utilizzare ' ' se avere l'attributo 'package' nel manifest xml? – Bootstrapper

+0

@ user2104070 No, l'autorizzazione deve contenere il nome del pacchetto. – Eran

+0

quindi ciò significa che se ho build differenti (in Android Studio) avrei bisogno di mantenere versioni separate di AndroidManifest per ciascuna (come i nomi dei pacchetti sarebbero diversi)? – Bootstrapper

40

Il problema è stato risolto, nel mio caso è stato un po 'più complicato.

  1. Verifica d'aver una connessione Internet attiva
  2. Verificare di avere il permesso di Internet nella vostra manifesta
  3. Assicurarsi che il nome del pacchetto è corretto come Eran menzionato
  4. Il tempo di dispositivo è impostato correttamente. Anche se tutto è perfetto, fallirà se l'orologio del dispositivo non è impostato correttamente.

L'orologio sbagliato ha causato problemi per me. :)

+1

Ho dimenticato di attivare il wifi! Grazie – JCarlos

+0

Sì, ho perso la connessione wifi e non me ne sono reso conto. Grazie. – ndland

+0

4 punti salvato il mio tempo –

3

Ho avuto lo stesso problema ma nessuna delle soluzioni di cui sopra ha risolto il problema nel mio caso. Fortunatamente l'ho risolto recentemente e voglio spiegare come, saltando aiuterà gli altri:

Nel mio caso, stavo registrando il servizio push in una classe di applicazione personalizzata (che viene eseguita prima di qualsiasi attività e penso sia dovuta a questo che alcune cose non sono state inizializzate in modo propositivo). La modifica all'attività principale ha risolto il problema.

public class MyCustomApp extends Application { 

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

} 
3

Ho avuto un problema simile. Ha funzionato bene su un google nexus (Android 4.4.2) ma non su un Samsung Galaxy s3 (Android 4.1.2). Stavo ricevendo SERVICE_NOT_AVAILABLE alla registrazione su Samsung. È arrivato il momento in cui Samsung è stato spento. Non era impostato per l'aggiornamento automatico con Network Time. Una volta ho risolto che GCM funzionava come un fascino. Grazie - Umesh

12

Per me - l'ora del dispositivo non era corretta. Ho modificato le impostazioni del dispositivo per utilizzare "Automatic date & time", provato di nuovo e tutto bene.

Cheers

+2

All'inferno con downvoters, questo è stato il problema anche nel mio caso. –

3

Per me c'era un problema di connessione. Cambia connessione internet risolto il mio problema

+1

Questo ha risolto anche il mio problema. Penso che sia un buon suggerimento che dovresti assicurarti che la tua rete funzioni quando vedi l'errore "SERVICE_NOT_AVAILABLE". –

3

Per quanto mi riguarda, ho disattivato "Accesso ai dati in background" per i servizi Google selezionando "Limita dati in background" in Opzione di utilizzo dati sul mio Galaxy S4. Appena ho acceso il problema risolto sulla rete del cellario. Su Wifi funzionava bene.

+1

E per me il problema era che non mi collegavo al WIFI locale. So che questo sembra stupido, ma quello che sto cercando di dire è che il networking può essere il problema. –

3

Nel mio caso, la soluzione era quella di aggiungere una nuova azione intent-filtro, REGISTRAZIONE, per il manifesto, 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> 

devo ammettere che sono sorpreso che questo funziona, dato che è manca dal tutorial, ma portarlo fuori definitivamente trasforma un ID di registrazione in un'eccezione.

Nota: utilizzo dell'emulatore Nexus 5 API 21 (Lollipop).

+1

È elencato nei nuovi documenti per questo: https://developers.google.com/cloud-messaging/android/client – Almo

16

SERVICE_NOT_AVAILABLE è uno dei problemi più frustranti con Google Cloud Messaging. È un'eccezione generata da GoogleCloudMessaging.register(SENDER_ID), la chiamata di funzione che registra il dispositivo per le notifiche push e restituisce un ID di registrazione.

  1. SERVICE_NOT_AVAILABLE può significare che il dispositivo dell'utente non è in grado di leggere la risposta alla richiesta di registrazione o che un codice di errore 500/503 è stato restituito dal server. Gli sviluppatori non hanno modo di correggere questo errore perché è alla fine di Google, quindi possiamo suggerire ciecamente che l'utente dovrebbe riprovare tra qualche ora.
  2. SERVICE_NOT_AVAILABLE può verificarsi su alcuni dispositivi anche se la registrazione è riuscita. Questo problema può essere risolto implementando un ricevitore broadcast alternativo per catturare il token quando la chiamata fallisce. Ho implementato questa soluzione alternativa e potrebbe aver risolto il problema per alcuni utenti, ma ho ricevuto ancora molti altri reclami SERVICE_NOT_AVAILABLE.
  3. SERVICE_NOT_AVAILABLE può verificarsi a causa di una libreria di Google Play Services obsoleta o mancante sul dispositivo. In questo caso, l'app potrebbe in teoria informare l'utente di aggiornare i servizi di Google Play aprendo la relativa scheda dell'app Google Play. Tuttavia, l'app non ha idea che questo sia il motivo per cui SERVICE_NOT_AVAILABLE è stato lanciato, quindi non può reindirizzare ciecamente l'utente alla pagina dell'app Google Play Services su Google Play.
  4. SERVICE_NOT_AVAILABLE può verificarsi quando l'orologio del dispositivo non è sincronizzato con la rete. Ancora una volta, gli sviluppatori non hanno modo di sapere che questo è il problema esatto, quindi possiamo suggerire ciecamente all'utente di verificare la sincronizzazione del loro orologio di sistema, sperando che siano uno dei pochi i cui orologi non siano sincronizzati.
  5. SERVICE_NOT_AVAILABLE può verificarsi quando un utente rooted ha eliminato l'app Hangouts/GTalk dal proprio dispositivo (perché lo ha considerato bloatware). GCM è implementato e gestito da Hangouts/GTalk, quindi non è possibile utilizzare GCM senza di esso.
  6. SERVICE_NOT_AVAILABLE può verificarsi se l'utente sta eseguendo un dispositivo su cui non sono installate API di Google (come Amazon Kindle). Niente da fare qui, questi utenti non riceveranno mai notifiche push dalla tua app.

Per saperne di più: http://eladnava.com/google-cloud-messaging-extremely-unreliable/

questi da soli i problemi erano abbastanza per farmi iniziare a cercare alternative GCM. Avrei ottenuto una recensione a 1 stella sulla mia app ogni giorno o due, con un commento contenente il messaggio di errore visualizzato quando è stato lanciato un SERVICE_NOT_AVAILABLE. Non c'era nulla che potessi fare per aiutare questi utenti, perché la maggior parte di loro lo stava ricevendo per motivi fuori dal loro controllo.

un'alternativa a Google Cloud Messaging

Pushy (https://pushy.me/) è un gateway di notifica push autonomo, completamente indipendente GCM. Mantiene la propria connessione socket in background, proprio come GCM, per ricevere notifiche push. Il protocollo sottostante è MQTT, un pub/sub protocol estremamente leggero, che utilizza pochissima larghezza di banda di rete e batteria.

Un enorme vantaggio di Pushy è che il codice per l'invio di una notifica push (dal server) e la registrazione del dispositivo per le notifiche push, è in realtà intercambiabile tra GCM e Pushy. Ciò rende super facile passare a Pushy dopo aver implementato GCM e aver dovuto abbandonarlo per la sua instabilità.

(Full disclosure: Ho fondato Pushy per i miei progetti e realizzato molte applicazioni potrebbero trarre vantaggio da un tale servizio)

+0

Può pushy.me dirmi quando il dispositivo ha una connessione attiva al server e quando è disconnesso. Voglio solo inviare push ai dispositivi collegati. – akshay202

+0

Assolutamente! La nostra API Device Info fornisce la presenza last_active del dispositivo del dispositivo: https://pushy.me/docs/api/device –

0

avevo girato di "Background accesso ai dati" per i servizi di Google. Deselezionando "Limita i dati in background" nell'opzione Utilizzo dati Funziona per me!

0

Per me goolge ha bloccato il mio IP !! Ho dovuto resettare la mia connessione DSL per ottenere un nuovo IP dal pool e tutto ha funzionato di nuovo, idk perché mi hanno bloccato, forse per provare molte app? Comunque sta funzionando ora, spero che questo aiuti qualcun altro :)

2

Per me il problema era che il telefono non era connesso a Internet. Mi disconnetto e mi collego al Wi-Fi e collaudo la connettività con il browser e provo di nuovo. Ha funzionato come un fascino :-)

0

Per me, il problema SERVICE_NOT_AVAILABLE era nel mio progetto di applicazione a causa della classe del ricevitore. Quindi ho risolto dopo aver implementato il ricevitore come il seguente. <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> Spero che ti possa aiutare :-).

-1

Dopo una lunga lotta sono riuscito a risolvere questo problema. Assicurati che l'app Google Play Services sia aggiornata e che la sincronizzazione in background non sia disabilitata sul telefono.

Problemi correlati