2

我继承了一个已经实现 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。这可能是问题吗?

相关问题: 在一台设备上获取 INVALID_SENDER,同时与另一台 GCM android 一起使用

4

1 回答 1

7

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

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

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

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

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

于 2013-09-12T15:07:59.627 回答