2016-01-05 6 views
8

sto seguendo l'esempio che Google fornisce per registrare il token GCM: https://developers.google.com/cloud-messaging/android/startSottoscrizione argomenti con Google Cloud Messenger modo, Invalid argument ricevuto

Ho generato correttamente il file google-services.json e io sono in grado di ricevere i token push. Ma quando sto cercando di iscriversi a qualsiasi argomento con il codice seguente:

// Register the user to the global topic. This will help the device to be register on GCM 
    GcmPubSub pubSub = GcmPubSub.getInstance(this); 
    pubSub.subscribe(token, "/topics/global", null); 

Esso genera l'eccezione INVALID_ARGUMENT:

01-05 14:05:24.435 D/RegIntentService(4330): java.io.IOException: INVALID_PARAMETERS 
01-05 14:05:24.435 D/RegIntentService(4330): at com.google.android.gms.iid.zzc.zzb(Unknown Source) 
01-05 14:05:24.435 D/RegIntentService(4330): at com.google.android.gms.iid.zzc.zza(Unknown Source) 
01-05 14:05:24.435 D/RegIntentService(4330): at com.google.android.gms.iid.InstanceID.zzc(Unknown Source) 
01-05 14:05:24.435 D/RegIntentService(4330): at com.google.android.gms.iid.InstanceID.getToken(Unknown Source) 
01-05 14:05:24.435 D/RegIntentService(4330): at com.google.android.gms.gcm.GcmPubSub.subscribe(Unknown Source) 
01-05 14:05:24.435 D/RegIntentService(4330): at gcm.play.android.samples.com.gcmquickstart.RegistrationIntentService.subscribeTopics(RegistrationIntentService.java:105) 
01-05 14:05:24.435 D/RegIntentService(4330): at gcm.play.android.samples.com.gcmquickstart.RegistrationIntentService.onHandleIntent(RegistrationIntentService.java:65) 
01-05 14:05:24.435 D/RegIntentService(4330): at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65) 
01-05 14:05:24.435 D/RegIntentService(4330): at android.os.Handler.dispatchMessage(Handler.java:99) 
01-05 14:05:24.435 D/RegIntentService(4330): at android.os.Looper.loop(Looper.java:137) 
01-05 14:05:24.435 D/RegIntentService(4330): at android.os.HandlerThread.run(HandlerThread.java:60) 

Questo è un esempio di gettoni push che mi riceve:

e3r6xnFGK3E:APA91bG9oY0A7QCf86BXXh8ADzycct5QJUONTXMH3pApCkcwty0A6UXo6zLLx3Hl3ubMgBY65ldxuZzSF20nahZAq-4SiUMRS0YYStJtldK85lzrO-xM5KvM_Jigpaka-RN5TLb8D1Op 

Ho controllato la documentazione relativa all'iscrizione di un argomento ma non c'è nulla che dica perché sto ricevendo l'eccezione INVALID_PARAMETER:

https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmPubSub.html#subscribe(java.lang.String, java.lang.String, android.os.Bundle)

Qualsiasi aiuto è apprezzato.

p.d. C'è il codice sorgente completo per registrare i gettoni:

import android.annotation.SuppressLint; 
import android.app.IntentService; 
import android.content.Intent; 
import android.os.Bundle; 
import android.os.ResultReceiver; 
import android.util.Log; 

import com.google.android.gms.gcm.GcmPubSub; 
import com.google.android.gms.gcm.GoogleCloudMessaging; 
import com.google.android.gms.iid.InstanceID; 


/** 
* Intent service used to retrieve and save the registration token needed 
* Extracted from here 
* https://github.com/googlesamples/google-services/blob/master/android/gcm/app/src/main/java/gcm/play/android/samples/com/gcmquickstart/RegistrationIntentService.java 
*/ 
public class RegistrationIntentService extends IntentService { 

    public static final String TAG = "RegistrationIntentService"; 
    public static final String INTENT_KEY_UPDATE_SERVER_TOKEN_CALLBACK = 
      "services.RegistrationIntentService.INTENT_KEY_UPDATE_SERVER_TOKEN_CALLBACK"; 

    private ResultReceiver mResultReceiver; 
    public static final String BUNDLE_KEY_GCM_TOKEN = 
      "services.RegistrationIntentService.BUNDLE_KEY_GCM_TOKEN"; 

    public RegistrationIntentService() { 
     super(TAG); 
    } 

    @SuppressLint("LongLogTag") 
    @Override 
    protected void onHandleIntent(Intent intent) { 
     // Get the result receiver 
     Bundle extras = intent.getExtras(); 
     if (extras != null && extras.containsKey(INTENT_KEY_UPDATE_SERVER_TOKEN_CALLBACK)) { 
      mResultReceiver = (ResultReceiver)extras.get(INTENT_KEY_UPDATE_SERVER_TOKEN_CALLBACK); 
     } 

     try { 
      InstanceID instanceId = InstanceID.getInstance(this); 
      String token = instanceId.getToken(getString(R.string.gcm_defaultSenderId), 
        GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); 
      Log.i(TAG, "GCM Registration Token: " + token); 

      // TODO: Send registration token to the server 
      if (mResultReceiver != null) { 
       Bundle bundle = new Bundle(); 
       bundle.putString(BUNDLE_KEY_GCM_TOKEN, token); 
       mResultReceiver.send(0, bundle); 
      } 

      // Register the user to the global topic. This will help the device to be register on GCM 
      GcmPubSub pubSub = GcmPubSub.getInstance(this); 
      pubSub.subscribe(token, "/topics/global", null); 
      Logger.v(TAG, "User correctly register to the global token"); 

     } catch (Exception e) { 
      Log.d(TAG, "Faield to complete token refresh", e); 
     } 
    } 
} 

E questo è il contenuto del google-services.json

{ 
    "project_info": { 
    "project_id": "NOT_SHOWN-aa10f", 
    "project_number": "11046079110", 
    "name": "NOT_SHOWN" 
    }, 
    "client": [ 
    { 
     "client_info": { 
     "mobilesdk_app_id": "1:11046079110:android:b918cc51ed907631", 
     "client_id": "android:NOT_SHOWN", 
     "client_type": 1, 
     "android_client_info": { 
      "package_name": "NOT_SHOWN" 
     } 
     }, 
     "oauth_client": [], 
     "api_key": [], 
     "services": { 
     "analytics_service": { 
      "status": 1 
     }, 
     "cloud_messaging_service": { 
      "status": 2, 
      "apns_config": [] 
     }, 
     "appinvite_service": { 
      "status": 1, 
      "other_platform_oauth_client": [] 
     }, 
     "google_signin_service": { 
      "status": 1 
     }, 
     "ads_service": { 
      "status": 1 
     } 
     } 
    } 
    ], 
    "client_info": [], 
    "ARTIFACT_VERSION": "1" 
} 
+0

Penso che il problema risieda nell'usare "questo" nell'ottenere le istanze. Cambiare 'InstanceID instanceId = InstanceID.getInstance (this);' a 'InstanceID instanceId = InstanceID.getInstance (getApplicationContext());' e anche 'GcmPubSub PubSub = GcmPubSub.getInstance (questo) ; ' a ' GcmPubSub pubSub = GcmPubSub.getInstance (getApplicationContext()); ' per accertarsi che si trovino nello stesso contesto. – gerardnimo

+0

Ciao: Grazie per la risposta. Non penso che questo sia il problema. Il codice funziona in quasi il 40% delle volte. Quindi, ci dovrebbe essere qualche cambiamento di condizione mentre il codice è in esecuzione. RegistrationIntentService si estende da IntentService, che si estende dal servizio, che si estende da ContextWrapper, che si estende dal contesto stesso. Non dovrebbe essere il problema. – jiahao

+0

Vedo. Hai controllato il token che stai utilizzando o stai utilizzando gcm.register() per ottenere token, questi potrebbero essere i problemi che hanno causato il problema. – gerardnimo

risposta

4

Sembra che nessuno ha risolvere questo problema così lontano, così ho vado a dare la soluzione che ho trovato.

Il problema era che abbiamo diversi processi che registrano il GCM. Quindi, ciò che accade nel 60% dei casi è che dopo aver registrato il nostro dispositivo, nella stessa app, l'altro registro di processo su GCM con il proprio mittente. Quindi, quando stavamo cercando di iscrivermi a un argomento, il token gcm non è valido perché lo stesso dispositivo, la stessa app ha registrato il gcm per un altro mittente.

Per risolvere il problema, ciò che abbiamo fatto è ottenere l'id del mittente da un altro processo, quindi collegarlo al nostro mittente.

Diciamo che il nostro ID mittente è "1234567", e il suo mittente ID è "7654321", così quando registriamo la nostra applicazione su GCM, invece di analizzare solo "1234567", usiamo "1234567,7654321", separati da coma.

Ciò ci consente di ottenere un token GCM valido sia per noi che per un altro processo, mentre se un altro processo registra il GCM dopo di noi, non invaliderà il proprio token GCM. (Il suo token GCM sarà ancora valido perché includiamo il suo mittente come parte della richiesta).

Cheers da Dubai!

+0

Sono interessato a questa risposta, tuttavia come si fa a "ottenere l'id del mittente da un altro processo, quindi collegarlo al nostro mittente". ? – Rippo

+0

È stato un po 'di tempo in cui ci stavo lavorando. Non sono sicuro della risposta giusta. L'id del mittente è qualcosa che hai nel Manifesto. Aggiungilo lì, credo. – jiahao