Search code examples
androidandroid-c2dmgoogle-cloud-messaging

GCM FC / sender id not set on constructor


I have gotten some strange StackTraces from users of my app recently:

Android Version: 2.3.5
Phone Model: GT-I9001
Stacktrace:
java.lang.IllegalStateException: sender id not set on constructor
at com.google.android.gcm.GCMBaseIntentService.getSenderIds(GCMBaseIntentService.java:125)
at com.google.android.gcm.GCMBaseIntentService.onHandleIntent(GCMBaseIntentService.java:237)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:59)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.os.HandlerThread.run(HandlerThread.java:60)

I am using Rev. 3 of the GCM lib and regarding to the documentation the senderID is not needed to be passed by the constructor anymore ( was that way in C2DM times ) - also this does not crash on my devices and on the devices of a lot of other users. Can somebody shed a light on what is happening on these devices and idealy has some workaround? A non working GCM for these users would be an option for me as device push is optional - but I do not want it to crash ..

Edit here is the source used: https://github.com/ligi/gobandroid/blob/master/src/org/ligi/gobandroid_hd/GCMIntentService.java


Solution

  • Did you override the method getSenderIds(Context context) from GCMBaseIntentService? From the source code, it mentioned if you do not pass in a SenderID in the constructor, then you need to override getSenderIds(Context context) to provide a SenderID.

    Here's the comment from the constructor:

    /**
     * Constructor that does not set a sender id, useful when the sender id
     * is context-specific.
     * <p>
     * When using this constructor, the subclass <strong>must</strong>
     * override {@link #getSenderIds(Context)}, otherwise methods such as
     * {@link #onHandleIntent(Intent)} will throw an
     * {@link IllegalStateException} on runtime.
     */
    protected GCMBaseIntentService() {
        this(getName("DynamicSenderIds"), null);
    }
    

    And the comment for getSenderIds():

    /**
     * Gets the sender ids.
     *
     * <p>By default, it returns the sender ids passed in the constructor, but
     * it could be overridden to provide a dynamic sender id.
     *
     * @throws IllegalStateException if sender id was not set on constructor.
     */
    protected String[] getSenderIds(Context context) {
        if (mSenderIds == null) {
            throw new IllegalStateException("sender id not set on constructor");
        }
        return mSenderIds;
    }