【问题标题】:Showing multiple notification messages with single id显示具有单个 id 的多条通知消息
【发布时间】:2013-04-11 15:44:30
【问题描述】:

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

理想情况是,每条通知消息都会轮流显示,大约 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 条消息。每条消息都会轮流出现。没有消息丢失。

【问题讨论】:

    标签: android


    【解决方案1】:

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

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

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

    来自乔的消息。

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

    您有 (n) 条消息。

    当用户按下Notification 时,您应该重定向到Activity,该ActivityListViewGridView 之类的形式显示所有内容,以显示您的所有消息

    【讨论】:

    • 我显示的信息是一系列的股票警报信息(要么高于价格要么低于价格)。因此,如果有 20 只股票,我需要以串行方式依次显示 20 条消息,每条消息显示 5 秒。
    【解决方案2】:

    我创建了自己的消息队列系统。不使用单一id,但能够实现我想要的

    如果同时发出多个通知请求,则只会显示 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);    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多