2

I inherited an application that already implemented GCM services and is working well enough.

I'm saying well enough because half the times, when the app launches, I get the error INVALID_SENDER and the other half I don't get it!

There is no difference between the times I get the error and the times I don't (or maybe I'm missing the difference).

I do get messages from GCM from time to time (when I don't get the INVALID_SENDER after logging in)

This is the registration code in the onCreate() of my main activity

private void registerGCM() throws Exception {
    GCMRegistrar.checkDevice(this);
    GCMRegistrar.checkManifest(this);
    registerReceiver(mHandleMessageReceiver, new IntentFilter(
            CommonUtilities.DISPLAY_MESSAGE_ACTION));
    final String regId = GCMRegistrar.getRegistrationId(this);
    if (regId.equals("")) {

        // Automatically registers application on startup.
        GCMRegistrar.register(this, CommonUtilities.SENDER_ID);
    } else {


        // Device is already registered on GCM, check server.
        if (GCMRegistrar.isRegisteredOnServer(this)) {


            ServerUtilities.register(mContext, regId);
        } else {
            // Try to register again, but not in the UI thread.
            // It's also necessary to cancel the thread onDestroy(),
            // hence the use of AsyncTask instead of a raw thread.
            final Context context = this;
            mRegisterTask = new AsyncTask<Void, Void, Void>() {

                @Override
                protected Void doInBackground(Void... params) {
                    boolean registered = ServerUtilities.register(context,                      regId);
                    if (!registered) {
                         GCMRegistrar.unregister(context);
                    }
                    return null;
                }

My Manifest file

 <receiver
        android:name="com.mixpanel.android.mpmetrics.GCMReceiver"
        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.says.broadcaster" />
        </intent-filter>
    </receiver>
    <receiver
        android:name="com.google.android.gcm.GCMBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>

            <!-- Receives the actual messages. -->
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <!-- Receives the registration id. -->
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

            <category android:name="com.says.broadcaster" />
        </intent-filter>
    </receiver>

The reason I have two receivers is that I get push notifications from the stats tracking API I'm using too, and they use GCM.

My app has a new version every week or so, and I was reading that I need to register for a new ID after an app update. Could this be the issue?

Related questions: Getting INVALID_SENDER on one device while its working with another GCM android

Community
  • 1
  • 1
Eyad Alama
  • 199
  • 1
  • 14
  • 1
    That's the first time I see an application with two receivers that accept GCM messages. I'm not sure that can work. It's more likely that one of the receivers will get all the messages, and the other will get none. How does your app register to GCM? Do you register once? Do you register with a single sender id? Have you tried to debug your app and see which code gives the `INVALID_SENDER` error? – Eran Sep 11 '13 at 14:50
  • I only register one of the receivers (which is shown in the code above). The other receiver is a part of a library and the registering is done by the library not by me. The thing is, the second receiver is always working and I can send messages to it whenever. But the first one (The normal GCM) works sometimes and other times it doesn`t. I register the first receiver with a Sender ID, but the second receiver is registered automatically and I can`t see its Sender ID. – Eyad Alama Sep 12 '13 at 02:27

1 Answers1

7

The Broadcasts sent by GCM seem to be ordered. This means they are delivered one at a time. It's possible that the receiver of the library sometimes gets called before your receiver, and it might prevent your receiver from being called (if it cancels the broadcast).

There are several ways to handle it. One way is to give your receiver a higher priority than the library's receiver. Just add the android:priority attribute to the intent-filter of both receiver, and give your receiver a higher priority.

Ordered broadcasts (sent with Context.sendOrderedBroadcast) are delivered to one receiver at a time. As each receiver executes in turn, it can propagate a result to the next receiver, or it can completely abort the broadcast so that it won't be passed to other receivers. The order receivers run in can be controlled with the android:priority attribute of the matching intent-filter; receivers with the same priority will be run in an arbitrary order.

When your broadcast receiver gets called, you should check that intent.getExtras ().get("from") contains the sender ID you are using. Only in this case you should handle the broadcast. If it's a different sender ID, it's probably the sender ID used by the library, and you should let the library handle it.

If that doesn't solve the problem, you can consider declaring only your receiver in the manifest, and forwarding the GCM broadcast to the other receiver when necessary.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • Hey man thank you for your reply really. I just started implementing this solution (because it wasn't high on the priory list). I set up the priory for both receivers and i'm checking in the higher priority receiver for the Sender_ID. My question is, what do I do when i find that this notification should be handled by the second receiver ? should I just return void in the onMessage() method for the first receiver ? – Eyad Alama Sep 23 '13 at 05:01
  • 1
    @EyadAlama You're welcome! I think you should write the logic in the `onReceive` method of the broadcast receiver. If you find that the notification should be handled by the second receiver, just call `setResultCode (Activity.RESULT_OK)` in the last line of that method (it has no return value). I think in that case the broadcast will be delivered to the other receiver. If, on the other hand, you handled the notification in the first receiver, call `setResultCode (Activity.RESULT_CANCELED)`. I'm not sure about it though. You'll have to try it and let me know if it worked :) – Eran Sep 25 '13 at 16:49
  • Well what I did for now is remove the second receiver of the library (We weren't really using its features). I also tried changing every possible configuration (Changing the context that is used to register/unregister, changing the name of the receiver in the XML file and every other thing that could be changed) and finally it`s working properly now. I even got a software that sends out GCM notifications to the device and i was able to fully test it. Thank you again :) – Eyad Alama Sep 26 '13 at 02:39
  • Hey @EyadAlama and Eran sorry for asking. But Could you please tell me details what i have to do to solve this problem. As i don't know xml and so-much android. Please tell me what i have to do. Thanks. – Ashoka Mondal Dec 13 '13 at 09:37