显示具有单个ID的多个通知消息

时间:2013-04-11 15:44:30

标签: android

我有几个同时发生的事件。我需要以串行方式向用户显示多条通知消息。

理想情况是,每条通知信息都会轮流显示,大约2秒钟。

我能得到的最接近的是使用多个id。但是,使用多个id有副作用,我不想要。最终会在状态栏上同时显示多条通知消息。

这会使用户的状态变得混乱,这不是我的意图。

使用多个ID(最终显示多个杂波消息)

int id = 0;
private void sendNotification(String message) {
    NotificationCompat.Builder mBuilder =
            new NotificationCompat.Builder(this.getActivity())
            .setSmallIcon(R.drawable.ic_notification)
            .setContentTitle("MyApp")
            .setTicker(message)
            .setAutoCancel(true)
            .setOnlyAlertOnce(true)
            .setDefaults(Notification.DEFAULT_SOUND)
            .setContentText(message);
    final NotificationManager mNotificationManager =
            (NotificationManager) this.getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
    mNotificationManager.notify(id++, mBuilder.build());   
}

但是,如果我不使用多个ID,但使用单个ID,则 只会显示1条消息,如果同时发出多个通知请求。每条消息都会轮流出现。没有消息丢失。

2 个答案:

答案 0 :(得分:3)

如果状态栏中只需要一个Notification,但您希望该消息指示所有应用的通知,则需要通过更改消息来管理单个Notification

每次您使用Notification重新发布sendNotification(message)时,Notification ticker文字都会更新。

例如,如果您在假设的收件箱中只有一个项目通知,则可以发布如下消息:

  

来自Joe的消息。

当您收到多条新消息时,请将其更改为:

  

你有(n)条消息。

当用户按下Notification时,您应该重定向到显示ActivityListView内所有内容的GridView,以显示所有消息

答案 1 :(得分:1)

我创建了自己的消息排队系统。不使用单一身份证,但能够实现我想要的目标

如果同时发出多个通知请求,则只会显示1条消息。每条消息都会轮流出现。没有消息丢失。

this.blockingQueue.offer(message);

这是完整的消息排队系统。

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    executor.submit(new NotificationTask());
}

private class NotificationTask implements Runnable {
    @Override
    public void run() {
        while (!executor.isShutdown()) {
            try {
                String message = blockingQueue.take();
                notification(message);
                // Allow 5 seconds for every message.
                Thread.sleep(Constants.NOTIFICATION_MESSAGE_LIFE_TIME);
            } catch (InterruptedException ex) {
                Log.e(TAG, "", ex);
                // Error occurs. Stop immediately.
                break;
            }                
        }

    }
}

@Override
public void onDestroy() {
    // Will be triggered during back button pressed.
    super.onDestroy();
    executor.shutdownNow();
    try {
        executor.awaitTermination(100, TimeUnit.DAYS);
    } catch (InterruptedException ex) {
        Log.e(TAG, "", ex);
    }
}

private void notification(String message) {
    NotificationCompat.Builder mBuilder =
        new NotificationCompat.Builder(this.getActivity())
        .setSmallIcon(R.drawable.ic_notification)
        .setContentTitle(this.getString(R.string.app_name))
        .setTicker(message)
        .setContentText(message)
        .setAutoCancel(true)
        .setOnlyAlertOnce(true);

    // Do we need to have sound effect?

    final NotificationManager mNotificationManager =
        (NotificationManager) this.getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
    final int id = atomicInteger.getAndIncrement();
    mNotificationManager.notify(id, mBuilder.build());

    Handler handler = new Handler(Looper.getMainLooper());
    handler.postDelayed(new NotificationManagerCancelRunnable(mNotificationManager, id), Constants.NOTIFICATION_MESSAGE_LIFE_TIME);
}

// Use static class, to avoid memory leakage.
private static class NotificationManagerCancelRunnable implements Runnable {
    private final NotificationManager notificationManager;
    private final int id;

    public NotificationManagerCancelRunnable(NotificationManager notificationManager, int id) {
        this.notificationManager = notificationManager;
        this.id = id;
    }

    @Override
    public void run() {
        notificationManager.cancel(id);
    }
}

// For notification usage. 128 is just a magic number.
private final ExecutorService executor = Executors.newSingleThreadExecutor();
private final BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(128);
private final AtomicInteger atomicInteger = new AtomicInteger(0);