状态栏通知,顾名思义,就是显示在屏幕顶部状态栏的通知信息。
它允许应用程序以不干扰当前Activity的方式将事件通知用户。与Toast那种一闪而过的提示不同,Notification会将信息保留在状态栏和通知窗口中,直到用户主动清除。
Notification与Toast的区别十分明显:
Toast相当于一个没有按钮的对话框,弹出几秒后自动消失,无法持久化。Notification则会停留在状态栏,即使应用关闭也不会消失,用户可以随时查看。这种特性使得Notification成为后台服务(Service)与用户通信的理想方式。当后台服务需要提醒用户某个事件并需要用户响应时,它不应该直接启动Activity,而是创建一个状态栏通知,让用户在方便时点击处理。
一个标准的Notification包含多个视觉元素:
小图标:显示在状态栏左侧,是通知最核心的视觉标识必须设置。标题:通知的主要内容概括,吸引用户眼球。内容文本:对通知的详细说明,让用户了解具体情况。时间戳:通知产生的时间,默认是系统发出通知的时间。大图标:在通知展开后显示,可用于显示应用logo或联系人头像。在Android 4.1(Jelly Bean)及更高版本中,通知还支持扩展布局,可以显示更多内容,如长段落文本或图片预览,用户可以通过双指滑动或pinch-zoom手势打开这些扩展视图。
创建和显示一个状态栏通知需要经过几个明确的步骤:
NotificationManager是Android系统提供的通知管理器,负责管理和运行所有通知。
// 获取NotificationManager对象
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
注意:NotificationManager是系统服务,不能直接实例化,必须通过getSystemService()方法获取。
在Android 4.0及以上版本,推荐使用Notification.Builder来构建通知:
// 创建Notification构造器
Notification.Builder mBuilder = new Notification.Builder(this);
使用Builder对象设置通知的各种属性:
// 设置通知小图标(必须)
mBuilder.setSmallIcon(R.drawable.notification_icon);
// 设置通知首次出现在状态栏的提示文字
mBuilder.setTicker("您有新消息了");
// 设置通知标题
mBuilder.setContentTitle("我的通知");
// 设置通知内容
mBuilder.setContentText("这是一条重要的通知");
// 设置通知产生的时间
mBuilder.setWhen(System.currentTimeMillis());
// 设置点击通知后自动取消
mBuilder.setAutoCancel(true);
PendingIntent是一种特殊的Intent,它允许外部应用(如Android系统)执行你应用内部的代码。
即使你的应用程序关闭,PendingIntent仍然有效。当用户点击通知时,系统会执行这个PendingIntent。
// 创建点击通知后要执行的Intent
Intent intent = new Intent(this, TargetActivity.class);
intent.putExtra("message", "这是从通知传递过来的数据");
// 创建PendingIntent
PendingIntent pendingIntent = PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
);
// 将PendingIntent设置到通知中
mBuilder.setContentIntent(pendingIntent);
最后,使用NotificationManager的notify()方法显示通知:
// 构建Notification对象
Notification notification = mBuilder.build();
// 发送通知,需要指定通知的唯一ID
private static final int NOTIFICATION_ID = 9527;
mNotificationManager.notify(NOTIFICATION_ID, notification);
通知ID在整个应用范围内唯一标识一个通知。如果你想更新某个已存在的通知,只需使用相同的ID再次调用notify()方法即可。
下面是一个完整的工作示例,包含发送和更新通知的功能:
public class MainActivity extends Activity {
private Button mSendButton, mUpdateButton;
private Context mContext;
private Notification.Builder mBuilder;
private PendingIntent mPendingIntent;
private Notification mNotification;
private NotificationManager mNotificationManager;
private final int NOTIFICATION_ID = 9527;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
}
private void init() {
mContext = this;
mSendButton = (Button) findViewById(R.id.sendButton);
mSendButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
sendNotification(mContext);
}
});
mUpdateButton = (Button) findViewById(R.id.updateButton);
mUpdateButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
updateNotification();
}
});
}
/**
* 发送通知
*/
private void sendNotification(Context context) {
// 创建点击通知后要启动的Activity
Intent intent = new Intent(mContext, MainActivity.class);
mPendingIntent = PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// 获取NotificationManager
mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// 创建Notification.Builder
mBuilder = new Notification.Builder(mContext);
// 设置通知属性
mBuilder.setWhen(System.currentTimeMillis()); // 通知产生的时间
mBuilder.setTicker("Ticker文本"); // 状态栏初始提示文本
mBuilder.setContentTitle("通知标题");
mBuilder.setContentInfo("附加信息");
mBuilder.setContentText("通知内容文本");
mBuilder.setContentIntent(mPendingIntent);
mBuilder.setPriority(Notification.PRIORITY_DEFAULT); // 设置优先级
mBuilder.setSmallIcon(R.drawable.ic_launcher); // 必须设置小图标
// 设置默认振动提醒(需要VIBRATE权限)
mBuilder.setDefaults(Notification.DEFAULT_VIBRATE);
// 设置通知为一个持续进行的通知(如后台任务)
mBuilder.setOngoing(false);
// 构建Notification对象
mNotification = mBuilder.build();
// 设置点击后自动取消
mNotification.flags = Notification.FLAG_AUTO_CANCEL;
// 发送通知
mNotificationManager.notify(NOTIFICATION_ID, mNotification);
}
/**
* 更新通知
*/
private void updateNotification() {
// 更新通知内容
mBuilder.setContentTitle("更新后的标题");
mBuilder.setContentInfo("更新后的信息");
mBuilder.setContentText("更新后的内容文本");
mNotification = mBuilder.build();
mNotification.flags = Notification.FLAG_AUTO_CANCEL;
// 使用相同的ID更新通知
mNotificationManager.notify(NOTIFICATION_ID, mNotification);
}
}
对应的布局文件main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/sendButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送通知"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dip" />
<Button
android:id="@+id/updateButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="更新通知"
android:layout_centerHorizontal="true"
android:layout_marginTop="250dip" />
</RelativeLayout>
别忘了在AndroidManifest.xml中添加振动权限(如果需要使用振动功能):
<uses-permission android:name="android.permission.VIBRATE"/>
你可以通过多种方式增强通知的提醒效果:
// 添加默认声音、振动和LED灯提醒
mBuilder.setDefaults(Notification.DEFAULT_ALL);
// 或单独设置各种提醒方式
mBuilder.setDefaults(Notification.DEFAULT_SOUND); // 默认声音
mBuilder.setDefaults(Notification.DEFAULT_VIBRATE); // 默认振动
mBuilder.setDefaults(Notification.DEFAULT_LIGHTS); // 默认LED灯
// 使用自定义声音
mBuilder.setSound(Uri.parse("file:///sdcard/notifications/sound.mp3"));
// 设置自定义振动模式
// 参数含义:延迟0ms,振动300ms,延迟500ms,振动700ms
long[] vibratePattern = {0, 300, 500, 700};
mBuilder.setVibrate(vibratePattern);
对于后台运行的任务,可以在通知中显示进度条:
// 对于确定进度的任务(如下载文件)
mBuilder.setProgress(100, 50, false); // 最大值100,当前进度50
// 对于不确定进度的任务(如正在同步)
mBuilder.setProgress(0, 0, true); // 显示循环进度条
// 任务完成后,移除进度条
mBuilder.setProgress(0, 0, false);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
通过设置标志位,可以控制通知的行为:
// 点击通知后自动取消
notification.flags = Notification.FLAG_AUTO_CANCEL;
// 将通知设置为持续进行的通知(如后台音乐播放)
notification.flags = Notification.FLAG_ONGOING_EVENT;
// 即使用户清除,通知也不会消失(直到应用主动取消)
notification.flags = Notification.FLAG_NO_CLEAR;
当需要更新已存在的通知时,只需使用相同的通知ID再次调用notify()方法。这在显示进度更新或累计事件数量时特别有用。
// 更新通知内容
mBuilder.setContentTitle("更新后的标题");
mBuilder.setContentText("下载进度:75%");
mBuilder.setProgress(100, 75, false);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
当通知不再需要时,应该主动取消它:
// 取消特定ID的通知
mNotificationManager.cancel(NOTIFICATION_ID);
// 取消本应用创建的所有通知
mNotificationManager.cancelAll();
设计良好的通知应当遵循以下原则:
清晰度:通知内容应该清晰易懂,帮助用户立即理解其含义。简洁性:避免过多的选项使界面过载,专注于核心信息。一致性:遵循Android设计指南,确保用户对通知的交互方式感到熟悉。用户控制:用户应该能够控制通知的行为,如设置免打扰等。什么时候使用通知? 当发生用户可能关心的事件,且不需要立即处理时。例如:新消息到达、文件下载完成、日历提醒等。
什么时候避免使用通知? 当需要用户立即关注并处理时,考虑使用对话框;当只是提供短暂反馈时,使用Toast可能更合适。
记住,滥用通知是惹恼用户最快的方式。一条精心设计的通知能够提升用户体验,而过多的通知则可能导致用户直接卸载你的应用。
掌握了Android Notification,你的应用就学会了在合适的时间、用合适的方式与用户交流。就像一位体贴的助手,它懂得何时该安静地递上纸条,而不是贸然打断主人的工作。
现在,就去为你应用的用户打造更加优雅、高效的通知体验吧,让他们在不被打扰的情况下,依然能感受到你的贴心服务。