GCM:如果应用程序不可见,则不会收到IntentService.sentBroadcast的消息

时间:2013-10-24 10:03:32

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

我正在尝试实施GCM客户端&服务器架构。到目前为止一切正常。

除外:当我的活动关闭并且我收到GCM的新通知时,通知会显示在通知栏中。到现在为止还挺好。但是当我点击通知时,我的活动已打开,但我的onReceive的{​​{1}}事件未被触发。 :( 如果活动已打开,则会BroadcastReceiver完全触发。

你知道吗,这里有什么不对?

干杯

克里斯

所以这是我的服务:

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());
  }
}

所有内容都是从Google Android教程的GCM示例中复制和改编的。

1 个答案:

答案 0 :(得分:3)

在通知栏中显示通知之前触发BroadcastReceiver。它包含显示通知的代码,并在点击时打开活动(除非它启动了执行该工作的意图服务)。

因此,如果您看到通知,则表示已触发BroadcastReceiver。

您无需额外的BroadcastReceiver即可将通知数据从第一个接收器传递到您的应用。如果您希望将通知数据传递给点击通知时正在启动的活动,您可以将其传递给用于启动该活动的意图。

假设您将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中执行此操作。)