在具有两个 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 can
t 看到它的发件人 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的主要内容,如果未能解决你的问题,请参考以下文章