在Android中,基本的Notification就是有事件发生的时候在屏幕顶端的Notification bar上显示一个图标。然后拉下Notification bar,点击Notification的项目,会调用相应的程序做处理。比如有新短信,就会出现短信的图标,拉下Notification bar,点击图标会调用短信查看程序。

我们先看一下Notification的Sample Code,然后逐行做解说,大致能了解它的基本构成。

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;

...

private void showNotification(Message msg, int id) {
NotificationManager notiManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.notiicon, msg
.getTitle(), System.currentTimeMillis());
notification.flags = Notification.FLAG_AUTO_CANCEL;
Intent intent = new Intent(this, MainActivity.class);
Bundle bundle = new Bundle();
bundle.putString("info", msg.getInfo());
intent.putExtras(bundle);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(this, id,
intent, PendingIntent.FLAG_UPDATE_CURRENT);

notification.setLatestEventInfo(this, msg.getTitle(), msg.getInfo(),
contentIntent);
notiManager.notify(id, notification);
}

首先导入三个类,Notification,NotificationManager,PendingIntent。 值得一提的是PendingIntent,它可以看做是Intent这封信的一个信封。PendingIntent基本上是Intent的包装和描述,对象收到PendingIntent后,可以得到其中的Intent再发出去。

NotificationManager notiManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

上面这一句,从系统中获得Notification服务,getSystemService()就是这么用,来获得系统服务的。

Notification notification = new Notification(R.drawable.notiicon, msg
.getTitle(), System.currentTimeMillis());
notification.flags = Notification.FLAG_AUTO_CANCEL;

然后是构造一个Notification,包括三个属性,图标,图标后面的文字,以及Notification时间部分显示出来的时间,通常使用当前时间。FLAG_AUTO_CANCEL说明Notification点击一次就消失。

Intent intent = new Intent(this, MainActivity.class);
Bundle bundle = new Bundle();
bundle.putString("info", msg.getInfo());
intent.putExtras(bundle);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK);

上面这部分Code,构造一个Intent,并且放进去一条信息。 FLAG_ACTIVITY_CLEAR_TOP, FLAG_ACTIVITY_NEW_TASK者两个FLAG表示优先寻找已经打开的应用,如果应用没有打开那么启动它。

PendingIntent contentIntent = PendingIntent.getActivity(this, id,
intent, PendingIntent.FLAG_UPDATE_CURRENT);

这一句代码把Intent包装在PendingIntent里,this是Context,id是PendingIntent的标志,如果id相同会被认为是一个。FLAG_UPDATE_CURRENT是指后来的PendingIntent会更新前面的。

notification.setLatestEventInfo(this, msg.getTitle(), msg.getInfo(),
contentIntent);
notiManager.notify(id, notification);

最后这两行添加状态栏的详细信息,包装PendingIntent给Notification,最后发送Notification。

转自:http://fanwei51880.blog.163.com/blog/static/32406740201052754236166/

另外一篇文章,供参考:

Android Notification 的使用 ” 的时候,发现有几个问题,特别是设置Notification的Intent使之能够像 QQ 或其他程序一样能够正确回调到之前已经放置在后台的Task中的对应Activity,而不是创建它的一个新实例。当然重点便是如何设置该 Activity 的 launchMode 与 Intent 的 Flags 了,说到这里,我不得不说一下今晚的调试经历,当然这里所说的所有的Notification都设置了FLAG_ONGOING_EVENT。

  按照 “ (转载)Android下Affinities和Task ”一文所说的,我们不难得出这样的结论:

  1、设置当用户触发Notification时所发出的Intent,如果设置 FLAG_ACTIVITY_CLEAR_TOP 与 FLAG_ACTIVITY_NEW_TASK ,而launchMode保持不变(即默认为:standard),则当用户用手点击Notification时,此时匹配到后台的Task,并把在堆栈中对应要启动的Activity之前的所有Activity全部清除掉,并且由于 standard 默认对于新的Intent总是创建新的Activity对象。因此存在于该Task中旧的Activity也会被清除掉,然后在该Task中创建新的 Activity对象。

  2、设置当用户触发Notification时所发出的Intent,如果设置 FLAG_ACTIVITY_CLEAR_TOP 与 FLAG_ACTIVITY_NEW_TASK,而launchMode设置为singleTop,则当用户用手点击Notification时,同1一样,只是存在于该Task中旧的Activity不会被清除掉,此时Intent传递给已经存在的Activity并不会创建新的Activity。

  上面得出的结论,经过返回测试,1是正确的,2却存在着很莫名奇妙的问题

  假设现在有个程序X,有2个Activity,分别是 A , B ,其中 A 是 设置了android.intent.action.MAIN的Activity(入口Activity),两者的launchMode都为默认的 standard,创建该Intent的代码如下:

  Intent intent = new Intent(this, A.class);

  intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);

  很明显我们设置的是当用户点击 Notification 时,应该出现的是 A Activity,但无论如何按home键退出当前Task,并使之成为后台Task,在从程序列表启动该程序总能恢复到Task顶端的Activity 给用户,如

当前 B,按home键,在从程序列表启动 X ,这个时候出现的Activity任然是 B,但按照如下的方法操作却会使得从程序列表启动 X,出现的是新创建的A Activity,其中经过Log打印得知下面的所有Activity都在同一个Task中

  1、打开程序出现A,从A startActivity 到B,按Home键,点Notification出现A,再从A startActivity 到 B,按Home键,从程序列表打开程序 出现新创建的实例A

  2、打开程序出现A,从A startActivity 到B,点Notification出现A,再从A startActivity 到B,按Home键,从程序列表打开程序也出现了新创建的实例A

  这里所说的“新创建的实例A”都是创建在同一Task中的新的A Activity实例,也就是说按照以上两种方法,再按返回键,出现的则是 B,再按返回键出现的则是 A。这里我实在想不出为什么会在同一Task中创建一个新的Activity,就算从程序列表打开程序的Intent使用了 FLAG_ACTIVITY_NEW_TASK标记,我也不知道为什么,如果有朋友知道,一定要告诉我。

  到这里,我开始发现 从程序列表启动 的优越性,因为不管是在什么时候按Home,再次从程序列表启动时,总能返回到Task的栈顶Activity。起初我想过一个办法,便是重载 Activity写一个类实现当onResume的时候更新Notification,然后我的所有Activity类都直接从该类继承,使得当按 Home 之后总能让Notification记住Task的栈顶Activity,就像QQ一样,但这种方法当然有点牵强,于是我开始看SDK 中 有关Home的Simple,终于发现了如果使用如下的Intent,便不会调用对应的Activity,而是调用Task中的栈顶Activity

  Intent intent = new Intent(Intent.ACTION_MAIN);

  intent.addCategory(Intent.CATEGORY_LAUNCHER);

  intent.setClass(this, Main.class);

  intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

  除了 setClass 可以换成使用 setClassName 绑定,FLAG_ACTIVITY_RESET_TASK_IF_NEEDED可以不设,其他的选项都缺一不可。设置ACTION_MAIN与 CATEGORY_LAUNCHER是把该Intent发给了系统对应创建程序的模块,然后系统该模块根据设定的包与类信息还有flags进行处理。当然所有的Intent工作原理都是这样,只是对 ACTION_MAIN - CATEGORY_LAUNCHAR 的处理较为特殊,使得总是显示Task栈顶的Activity而不是setClass设定的Activity类。

更多相关文章

  1. 在 Android(安卓)中调用二进制可执行程序(native executable )
  2. Android(1)
  3. andorid自定义progress
  4. 【全球首个】Android声纹识别程序 SuperLock 2.3 Beta 抢先发送
  5. Android(安卓)C/C++ 开发
  6. 【Android】AndroidManifest 清单文件以及权限详解
  7. 交付混合了 JSON 的 Android(安卓)应用程序
  8. root 后的android 无线传屏(服务器端与客户端)
  9. 如何为平板电脑开发android应用程序?

随机推荐

  1. 在 Eclipse 中导入 Android 示例程序
  2. Android 横竖屏切换时候重新进行数据请求
  3. Android安卓应用版本命名规范
  4. Android开发面试经——2.常见Android基础
  5. 经典的大牛博客推荐
  6. Android UI事件处理[isInTouchMode()]
  7. 带着问题学习 Android Handler 消息机制
  8. Android(安卓)铃音设置分析
  9. android ZygoteInit.java文件解析 从main
  10. Android ApiDemos 系列解析【View-ImageV