应用程序启动时收到奇怪的推送消息
Weird push message received on app start
我的推送服务捕获了一条奇怪的推送消息:
Bundle[{CMD=RST_FULL, from=google.com/iid, android.support.content.wakelockid=1}]
昨天才开始发生,我无法确定是哪个代码更改造成的。有没有人以前看过这条消息,也许知道它来自哪里以及为什么?
我今天发现了同样的问题。首先,此消息必须来自 google 本身(from=google.com/iid),否则 from 属性将是您的项目在 google 开发人员控制台中的 ID(即475832179747)。但可以肯定的是,我关闭了我们的应用程序服务器,但我仍然收到消息。
我在 Google 云消息服务器上新注册时总是收到它。这不是一个大问题,因为您可以通过 intent-action 过滤消息,但我真的很想知道它的用途。
我至少在华硕平板电脑上遇到了同样的事情
可能会在更多设备上使用,但我还没有机会看一看
我正在 Intent.getExtras() 中寻找一些特定的字符串,因此修复很简单,如果它们不存在,则忽略整个问题。
来自 Google 的人出现并解释发生了什么的可能性有多大?
For existing apps that extend a WakefulBroadcastReceiver, Google
recommends migrating to GCMReceiver and GcmListenerService. To
migrate:
- In the app manifest, replace your GcmBroadcastReceiver with "com.google.android.gms.gcm.GcmReceiver", and replace the current
service declaration that extends IntentService to the new
GcmListenerService
- Remove the BroadcastReceiver implementation from your client code
- Refactor the current IntentService service implementation to use GcmListenerService For details, see the example manifest.
似乎 google 将扩展 IntentService 以处理 gcms 的 GCMIntentService 拆分为两个服务,一个扩展 GcmListenerService 将处理收到的消息,另一个单独过滤 iid.InstanceID 以过滤掉收到的通知第一次安装,
这是来自新的 gcm android 指南
<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
您的应用收到此消息是因为它已从备份中恢复数据。由于备份可能包含注册令牌,因此发送此广播告诉您的应用获取新令牌,因为备份的令牌将不起作用。
这是为新 GCM APIs 设计的,它会导致调用您的 InstanceIdListenerService 实现的 onTokenRefresh() 方法,您的应用程序应在此处再次获取其所有令牌。
不幸的是,如果您正在编写自己的 BroadcastReceiver,这些消息将是意外的,并可能导致您的应用程序崩溃。正确的做法是过滤 "from" 字段,如果您看到其中一条消息,请再次向 GCM 注册,因为您的令牌可能无效。
如果您在恢复应用程序数据的全新安装情况之外收到这些消息,请post到android-gcm邮件列表。
按照@morepork 的建议查看更新后的GCM API Docs。
For existing apps that extend a WakefulBroadcastReceiver, Google
recommends migrating to GCMReceiver and GcmListenerService. To
migrate:
In the app manifest, replace your GcmBroadcastReceiver with "com.google.android.gms.gcm.GcmReceiver", and replace the current service declaration that extends IntentService to the new GcmListenerService
Remove the BroadcastReceiver implementation from your client code
Refactor the current IntentService service implementation to use GcmListenerService
For details, see the example manifest and code samples in this page.
来自他们的 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);
我在迁移 GCM->FCM 时遇到了这个问题,只接收了 wakelockid
个元素,来自:
- firebase 控制台
- 邮递员转载请求如下:
{
"to": "<your token from FirebaseInstanceId.getInstance().getToken()>",
"notification": {
"body": "Hello",
"title": "This is test message."
}
}
我还复制了 google quickstart firebase messaging 中的所有代码。
一切都应该没问题。然而,在所有测试之后,我决定仔细检查我的 gradle 库版本。所以我将它们增加到最新的数字。从那时起我开始正确接收消息。
我推荐的最快的解决方案是从 GitHub 下载项目并尝试这是否适合您。下一步是将此代码复制到您的项目中。如果在一个项目中一切正常,您至少有一个 standing/working 点可以开始。
有传言说 android 工作室导致了这个问题 - 但事实并非如此。我查过了。
您可以使用相同的旧令牌(来自 gcm)并且不接收消息是真的,但是如果您有像我一样的情况 migrating
,那么应该将令牌刷新为新令牌你应该处理它..
我的推送服务捕获了一条奇怪的推送消息:
Bundle[{CMD=RST_FULL, from=google.com/iid, android.support.content.wakelockid=1}]
昨天才开始发生,我无法确定是哪个代码更改造成的。有没有人以前看过这条消息,也许知道它来自哪里以及为什么?
我今天发现了同样的问题。首先,此消息必须来自 google 本身(from=google.com/iid),否则 from 属性将是您的项目在 google 开发人员控制台中的 ID(即475832179747)。但可以肯定的是,我关闭了我们的应用程序服务器,但我仍然收到消息。
我在 Google 云消息服务器上新注册时总是收到它。这不是一个大问题,因为您可以通过 intent-action 过滤消息,但我真的很想知道它的用途。
我至少在华硕平板电脑上遇到了同样的事情
可能会在更多设备上使用,但我还没有机会看一看
我正在 Intent.getExtras() 中寻找一些特定的字符串,因此修复很简单,如果它们不存在,则忽略整个问题。
来自 Google 的人出现并解释发生了什么的可能性有多大?
For existing apps that extend a WakefulBroadcastReceiver, Google recommends migrating to GCMReceiver and GcmListenerService. To migrate:
- In the app manifest, replace your GcmBroadcastReceiver with "com.google.android.gms.gcm.GcmReceiver", and replace the current service declaration that extends IntentService to the new GcmListenerService
- Remove the BroadcastReceiver implementation from your client code
- Refactor the current IntentService service implementation to use GcmListenerService For details, see the example manifest.
似乎 google 将扩展 IntentService 以处理 gcms 的 GCMIntentService 拆分为两个服务,一个扩展 GcmListenerService 将处理收到的消息,另一个单独过滤 iid.InstanceID 以过滤掉收到的通知第一次安装, 这是来自新的 gcm android 指南
<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
您的应用收到此消息是因为它已从备份中恢复数据。由于备份可能包含注册令牌,因此发送此广播告诉您的应用获取新令牌,因为备份的令牌将不起作用。
这是为新 GCM APIs 设计的,它会导致调用您的 InstanceIdListenerService 实现的 onTokenRefresh() 方法,您的应用程序应在此处再次获取其所有令牌。
不幸的是,如果您正在编写自己的 BroadcastReceiver,这些消息将是意外的,并可能导致您的应用程序崩溃。正确的做法是过滤 "from" 字段,如果您看到其中一条消息,请再次向 GCM 注册,因为您的令牌可能无效。
如果您在恢复应用程序数据的全新安装情况之外收到这些消息,请post到android-gcm邮件列表。
按照@morepork 的建议查看更新后的GCM API Docs。
For existing apps that extend a WakefulBroadcastReceiver, Google recommends migrating to GCMReceiver and GcmListenerService. To migrate:
In the app manifest, replace your GcmBroadcastReceiver with "com.google.android.gms.gcm.GcmReceiver", and replace the current service declaration that extends IntentService to the new GcmListenerService
Remove the BroadcastReceiver implementation from your client code
Refactor the current IntentService service implementation to use GcmListenerService
For details, see the example manifest and code samples in this page.
来自他们的 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);
我在迁移 GCM->FCM 时遇到了这个问题,只接收了 wakelockid
个元素,来自:
- firebase 控制台
- 邮递员转载请求如下:
{
"to": "<your token from FirebaseInstanceId.getInstance().getToken()>",
"notification": {
"body": "Hello",
"title": "This is test message."
}
}
我还复制了 google quickstart firebase messaging 中的所有代码。 一切都应该没问题。然而,在所有测试之后,我决定仔细检查我的 gradle 库版本。所以我将它们增加到最新的数字。从那时起我开始正确接收消息。
我推荐的最快的解决方案是从 GitHub 下载项目并尝试这是否适合您。下一步是将此代码复制到您的项目中。如果在一个项目中一切正常,您至少有一个 standing/working 点可以开始。
有传言说 android 工作室导致了这个问题 - 但事实并非如此。我查过了。
您可以使用相同的旧令牌(来自 gcm)并且不接收消息是真的,但是如果您有像我一样的情况 migrating
,那么应该将令牌刷新为新令牌你应该处理它..