GCM:如果应用程序不可见,则不会收到 IntentService.sentBroadcast 的消息
Posted
技术标签:
【中文标题】GCM:如果应用程序不可见,则不会收到 IntentService.sentBroadcast 的消息【英文标题】:GCM: messages by IntentService.sentBroadcast are not received if application is not visible 【发布时间】:2013-10-24 10:03:32 【问题描述】:我正在尝试实现 GCM 客户端和服务器架构。到目前为止一切正常。
例外:当我的活动关闭并且我收到 GCM 的新通知时,通知会显示在通知栏中。到现在为止还挺好。但是当我点击通知时,我的活动被打开,但我的BroadcastReceiver
的onReceive
事件没有被触发。 :(
如果Activity打开了,onReceive
就完美触发了。
你知道这里有什么问题吗?
干杯
克里斯
这就是我的服务:
package xy;
import ...;
public class GcmIntentService extends IntentService
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public GcmIntentService()
super("GcmIntentService");
@Override
protected void onHandleIntent(Intent intent)
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) // has effect of unparcelling Bundle
final int notificationID = (int) (Math.random() * 100000000);
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType))
sendNotification("GCM notification: Send error", extras.toString(), notificationID);
else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType))
sendNotification("Deleted messages on server", extras.toString(), notificationID);
// If it's a regular GCM message, do some work.
else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType))
sendNotification(extras.getString(Utils.TICKER_TITLE_MESSAGE_KEY), extras
.getString(Utils.TICKER_TEXT_MESSAGE_KEY), notificationID);
Intent intentToBroadCast = new Intent(Utils.DISPLAY_MESSAGE_ACTION);
intentToBroadCast.putExtra(Utils.MESSAGE_EXTRA_BUNDLE_KEY, extras);
intentToBroadCast.putExtra(Utils.NOTIFICATION_ID_KEY, notificationID);
sendBroadcast(intentToBroadCast);
// Release the wake lock provided by the WakefulBroadcastReceiver.
GcmBroadcastReceiver.completeWakefulIntent(intent);
private void sendNotification(final String aTitle, final String aText, final int aNotificationID)
mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this,
DemoActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this).setSmallIcon(
R.drawable.ic_stat_gcm).setContentTitle(aTitle).setStyle(
new NotificationCompat.BigTextStyle().bigText(aText)).setContentText(aText);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(aNotificationID, mBuilder.build());
这是我活动中的接收器,用于显示传入的消息:
public class GcmResultReceiver extends BroadcastReceiver
@Override
public void onReceive(Context context, Intent intent)
Bundle extras = intent.getBundleExtra(Utils.MESSAGE_EXTRA_BUNDLE_KEY);
String s = extras.getString(Utils.CONTENT_TITLE_MESSAGE_KEY) + "\n"
+ extras.getString(Utils.CONTENT_TEXT_MESSAGE_KEY);
mDisplay.setText(s);
int notificationID = intent.getIntExtra(Utils.NOTIFICATION_ID_KEY, -1);
if (-1 != notificationID) m_SentNotificationIDs.add(notificationID);
if (m_IsVisible)
clearNotifications();
;
所有内容都是从 Google android 教程中的 GCM 示例复制和改编的。
【问题讨论】:
【参考方案1】:在通知栏显示通知之前触发 BroadcastReceiver。它包含显示通知并在被点击时打开 Activity 的代码(除非它正在启动执行该工作的 Intent 服务)。
因此,如果您看到通知,则表示已触发 BroadcastReceiver。
您不需要额外的 BroadcastReceiver 来将通知数据从第一个接收器传递到您的应用程序。如果您希望在点击通知时将通知数据传递给正在启动的 Activity,您可以将其传递给用于启动该 Activity 的 Intent。
假设您将sendNotification
调用更改为:
sendNotification(extras, notificationID);
然后你可以这样实现:
private void sendNotification(Bundle extras, final int aNotificationID)
mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
Intent demoIntent = new Intent(this, DemoActivity.class);
demoIntent.putExtras (extras);
demoIntent.putExtra (Utils.NOTIFICATION_ID_KEY, notificationID);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, demoIntent, 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this).setSmallIcon(
R.drawable.ic_stat_gcm).setContentTitle(extras.getString(Utils.TICKER_TITLE_MESSAGE_KEY)).setStyle(
new NotificationCompat.BigTextStyle().bigText(extras.getString(Utils.TICKER_TEXT_MESSAGE_KEY))).setContentText(extras.getString(Utils.TICKER_TEXT_MESSAGE_KEY));
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(aNotificationID, mBuilder.build());
这样,您的DemoActivity
将获得通知 ID 和所有保存通知数据的附加信息。
您可以在您的活动的onCreate
中访问它们(或者最好在onResume
中进行,以防您的活动已经开始)。
【讨论】:
那么,我该如何调试呢?如果我在 Eclipse 中设置断点以在我的三星上进行调试,这就是我所看到的:派生的WakefulBroadcastReceiver
类中的 onReceive
对于每条消息总是触发两次。然后派生的IntentService
类中的onHandleIntent
总是被触发一次。但是派生的BroadcastReceiver
类中的onReceive
只有在应用在屏幕上时才会触发。
顺便说一句:我把sendBroadcast
放在派生的IntentService.onHandleIntent
中。这是正确的吗?
@ChristianGraf 我看不出有任何理由从意图服务发送广播。你发送什么广播,它的目的是什么?至于调试,如果应用程序在收到通知之前没有运行,我不确定如何将应用程序连接到调试器。尝试添加调试打印并检查您的 logcat。
好吧,我想,我们要说到点子上了。我在 ònHandleIntent 中收到 GCM 消息。我尝试将此消息发送到我的应用程序/活动。为此,我使用了 sendBroadcast 调用。显然这不是正确的方法?!明天要附上日志和打印件。
@ChristianGraf 但是如果您已经在显示通知,并且点击通知会打开您的活动,为什么不直接(通过意图)将消息数据传递给该活动?以上是关于GCM:如果应用程序不可见,则不会收到 IntentService.sentBroadcast 的消息的主要内容,如果未能解决你的问题,请参考以下文章
当应用程序一天不活动时,GCM 推送通知不会出现在 iPhone 上