Getting GCM Error: INVALID_SENDER occasionally in

2019-01-15 11:15发布

问题:

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

回答1:

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.