应用程序启动时收到奇怪的推送消息

时间:2015-05-27 10:10:44

标签: android push-notification google-cloud-messaging

我的推送服务捕获了一条奇怪的推送消息:

Bundle[{CMD=RST_FULL, from=google.com/iid, android.support.content.wakelockid=1}]

昨天刚开始发生,我无法确定哪个代码更改应该归咎于此。有没有人见过这个消息,也许知道它来自哪里以及为什么?

6 个答案:

答案 0 :(得分:20)

您的应用收到此消息,因为它已从备份中恢复数据。由于备份可能包含注册令牌,因此会发送此广播,告知您的应用获取新令牌,因为备份令牌将无效。

这适用于新的GCM APIs,它将导致您的InstanceIdListenerService实现的onTokenRefresh()方法被调用,您的应用应该再次获取其所有标记。

不幸的是,如果您正在编写自己的BroadcastReceiver,这些消息将是意外的,并可能导致您的应用程序崩溃。正确的做法是过滤"来自"字段,如果您看到其中一条消息,请再次向GCM注册,因为您的令牌可能无效。

如果您在正在恢复应用程序数据的全新安装情况之外收到这些消息,请发送到android-gcm邮件列表。

答案 1 :(得分:13)

请参阅@morepork建议更新的GCM API Docs

  

对于扩展WakefulBroadcastReceiver的现有应用程序,Google   建议迁移到GCMReceiver和GcmListenerService。至   迁移:

     

在应用清单中,将您的GcmBroadcastReceiver替换为“com.google.android.gms.gcm.GcmReceiver”,并将当前扩展IntentService的服务声明替换为新的GcmListenerService

     

从客户端代码中删除BroadcastReceiver实现

     

重构当前的IntentService服务实现以使用GcmListenerService

     

有关详细信息,请参阅此页面中的示例清单和代码示例。

sample code开始,它很容易理解。

的AndroidManifest.xml

<receiver
    android:exported="true"
    android:name="com.google.android.gms.gcm.GcmReceiver"
    android:permission="com.google.android.c2dm.permission.SEND">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
        <category android:name="com.example.client"/>
    </intent-filter>
</receiver>

<service
    android:name=".MyGcmListenerService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
    </intent-filter>
</service>

<service
    android:name=".MyInstanceIdListenerService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.android.gms.iid.InstanceID"/>
    </intent-filter>
</service>

<service
    android:name=".MyGcmRegistrationService"
    android:exported="false">
</service>

MyGcmListenerService.java

public class MyGcmListenerService extends GcmListenerService {
    @Override
    public void onMessageReceived(String from, Bundle data) {
        final String message = data.getString("message");
        makeNotification(message);
    }
}

MyGcmRegistrationService.java

public class MyGcmRegistrationService extends IntentService {
    private static final String TAG = "MyRegistrationService";
    private static final String GCM_SENDER_ID = "XXXXXXXXXXXX";
    private static final String[] TOPICS = {"global"};

    public MyGcmRegistrationService() {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        try {
            synchronized (TAG) {
                InstanceID instanceID = InstanceID.getInstance(this);
                String token = instanceID.getToken(GCM_SENDER_ID,
                        GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
                sendTokenToServer(token);
                subscribeTopics(token);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void subscribeTopics(String token) throws IOException {
        for (String topic : TOPICS) {
            GcmPubSub pubSub = GcmPubSub.getInstance(this);
            pubSub.subscribe(token, "/topics/" + topic, null);
        }
    }
}

MyInstanceIdListenerService.java

public class MyInstanceIdListenerService extends InstanceIDListenerService {
    public void onTokenRefresh() {
        Intent intent = new Intent(this, MyGcmRegistrationService.class);
        startService(intent);
    }
}

然后您可以用

替换旧的注册码
Intent intent = new Intent(this, MyGcmRegistrationService.class);
startService(intent);

答案 2 :(得分:7)

我今天意识到同样的问题。首先,此消息必须来自谷歌本身(来自= google.com / iid),否则from属性将是您在谷歌开发者控制台中的项目的ID(即475832179747)。但可以肯定的是,我关闭了我们的应用程序服务器,但仍然收到了消息。

当我在Google Cloud Messaging服务器上新注册时,我总是收到它。这不是一个大问题,因为你可以通过意图动作过滤消息,但我真的想知道它的目的。

答案 3 :(得分:2)

  

对于扩展WakefulBroadcastReceiver的现有应用程序,Google   建议迁移到GCMReceiver和GcmListenerService。至   迁移:

     
      
  • 在应用清单中,将您的GcmBroadcastReceiver替换为“com.google.android.gms.gcm.GcmReceiver”,并替换当前   将IntentService扩展到新的服务声明   GcmListenerService
  •   
  • 从客户端代码中删除BroadcastReceiver实现
  •   
  • 重构当前的IntentService服务实现以使用GcmListenerService有关详细信息,请参阅示例清单。
  •   

似乎谷歌拆分GCMIntentService,扩展了IntentService以处理gcms到两个服务,一个扩展GcmListenerService来处理收到的消息,另一个扩展过滤iid.InstanceID分别过滤掉第一次安装收到的通知, 这是来自新的gcm安卓指南

<service
    android:name="com.example.MyGcmListenerService"
    android:exported="false" >
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    </intent-filter>
</service>
<service
    android:name="com.example.MyInstanceIDListenerService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.android.gms.iid.InstanceID"/>
    </intent-filter>
</service>

https://developers.google.com/cloud-messaging/android/client

答案 4 :(得分:0)

至少在华硕平板电脑上发生同样的事情

可能在更多设备上,但我还没有机会看一眼

我在Intent.getExtras()中寻找一些特定的字符串,所以修复很简单,如果它们不存在则忽略整个事情。

Google的某些人有什么机会出现并解释发生了什么?

答案 5 :(得分:0)

我在迁移GCM-&gt; FCM时出现此问题,仅接收wakelockid元素:

  • firebase控制台
  • 邮递员转发请求,请求如下:

{ "to": "<your token from FirebaseInstanceId.getInstance().getToken()>", "notification": { "body": "Hello", "title": "This is test message." } }

此外,我还复制了Google quickstart firebase messaging中的所有代码。 一切都应该没问题。但是,在所有测试之后,我决定仔细检查我的gradle libs版本。所以我把它们增加到了最新的数字。从那时起,我开始正确地收到消息。

我建议从GitHub下载项目的最快解决方案,如果这对您有用,请尝试。下一步是将此代码复制到您的项目中。如果在一个项目中一切正常,您至少有一个站立/工作点从哪里开始。

有传言称android studio正在引发这个问题 - 但事实并非如此。我查了一下。

你可以使用相同的旧令牌(来自gcm)并且不接收消息,但如果你有像我这样migrating的同一个案例,那么令牌应该刷新到新的令牌应该处理它..