我的推送服务捕获了一条奇怪的推送消息:
Bundle[{CMD=RST_FULL, from=google.com/iid, android.support.content.wakelockid=1}]
昨天刚开始发生,我无法确定哪个代码更改应该归咎于此。有没有人见过这个消息,也许知道它来自哪里以及为什么?
答案 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
元素:
{
"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
的同一个案例,那么令牌应该刷新到新的令牌应该处理它..