在具有两个 GCM 广播接收器的应用中偶尔出现 GCM 错误:INVALID_SENDER

Posted

技术标签:

【中文标题】在具有两个 GCM 广播接收器的应用中偶尔出现 GCM 错误:INVALID_SENDER【英文标题】:Getting GCM Error: INVALID_SENDER occasionally in an app that has two GCM BroadcastReceivers 【发布时间】:2013-09-11 06:42:24 【问题描述】:

我继承了一个已经实现 GCM 服务并且运行良好的应用程序。

我说得很好,因为一半时间,当应用程序启动时,我收到错误 INVALID_SENDER 而另一半我不明白!

我得到错误的时间和我没有得到错误的时间之间没有区别(或者我可能错过了差异)。

我确实不时收到来自 GCM 的消息(当我登录后没有收到 INVALID_SENDER 时)

这是我主要活动onCreate()中的注册码

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;
                

我的清单文件

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

我有两个接收器的原因是我从我正在使用的统计跟踪 API 获得推送通知,它们使用 GCM。

我的应用程序每周左右都有一个新版本,我读到我需要在应用程序更新后注册一个新 ID。这可能是问题吗?

相关问题: Getting INVALID_SENDER on one device while its working with another GCM android

【问题讨论】:

这是我第一次看到一个应用程序有两个接受 GCM 消息的接收器。我不确定这是否可行。更有可能的是,其中一个接收者会收到所有消息,而另一个不会收到任何消息。您的应用如何注册到 GCM?你注册一次吗?您是否使用单个发件人 ID 进行注册?您是否尝试过调试您的应用并查看哪个代码给出了INVALID_SENDER 错误? 我只注册了一个接收器(如上面的代码所示)。另一个接收器是图书馆的一部分,注册是由图书馆而不是我完成的。问题是,第二个接收器一直在工作,我可以随时向它发送消息。但是第一个(正常的 GCM)有时会工作,有时它不会t. I register the first receiver with a Sender ID, but the second receiver is registered automatically and I cant 看到它的发件人 ID。 【参考方案1】:

GCM 发送的广播似乎是有序的。这意味着它们一次交付一个。库的接收器有时可能会在您的接收器之前被调用,这可能会阻止您的接收器被调用(如果它取消了广播)。

有几种方法可以处理它。一种方法是给您的接收器比图书馆的接收器更高的优先级。只需将android:priority 属性添加到两个接收器的intent-filter,并为您的接收器赋予更高的优先级。

有序广播(使用 Context.sendOrderedBroadcast 发送)一次传送到一个接收器。当每个接收器依次执行时,它可以将结果传播给下一个接收器,或者它可以完全中止广播,这样它就不会被传递给其他接收器。运行的订单接收器可以通过匹配intent-filter的android:priority属性来控制;具有相同优先级的接收器将以任意顺序运行。

当您的广播接收器被调用时,您应该检查 intent.getExtras ().get("from") 是否包含您正在使用的发送者 ID。只有在这种情况下,您才应该处理广播。如果是不同的发件人ID,则可能是库使用的发件人ID,您应该让库处理。

如果这不能解决问题,您可以考虑在清单中仅声明您的接收器,并在必要时将 GCM 广播转发到另一个接收器。

【讨论】:

嘿,谢谢你的回复。我刚刚开始实施这个解决方案(因为它在修道院列表中并不高)。我为两个接收器都设置了优先级,并且正在检查 Sender_ID 的更高优先级接收器。我的问题是,当我发现这个通知应该由第二个接收者处理时,我该怎么办?我应该在第一个接收者的 onMessage() 方法中返回 void 吗? @EyadAlama 不客气!我认为您应该在广播接收器的onReceive 方法中编写逻辑。如果您发现通知应该由第二个接收者处理,只需在该方法的最后一行调用setResultCode (Activity.RESULT_OK)(它没有返回值)。我认为在这种情况下,广播将被传递给另一个接收器。另一方面,如果您在第一个接收者中处理了通知,请致电setResultCode (Activity.RESULT_CANCELED)。不过我不确定。你必须尝试一下,如果它有效,请告诉我:) 好吧,我现在做的是删除库的第二个接收器(我们并没有真正使用它的功能)。我还尝试更改所有可能的配置(更改用于注册/取消注册的上下文,更改 XML 文件中接收器的名称以及所有其他可以更改的内容),最后它现在可以正常工作了。我什至有一个向设备发送 GCM 通知的软件,我能够对其进行全面测试。再次感谢你:) 嘿 @EyadAlama 和 Eran 很抱歉问这个问题。但是你能告诉我细节我必须做些什么来解决这个问题。因为我不知道xml和这么多的android。请告诉我我必须做什么。谢谢。

以上是关于在具有两个 GCM 广播接收器的应用中偶尔出现 GCM 错误:INVALID_SENDER的主要内容,如果未能解决你的问题,请参考以下文章

应用关闭时无法接收 GCM

android中的两个gcm接收器

android 广播接收不到

GCM'错误:未注册'

GCM 会在 2.1 中崩溃 Android 应用程序吗?

Android - 一个应用程序中有两个或多个 GCM 令牌