在做一个IM项目,当收到消息监听时,需要后台服务发送一个通知,研究了一下Notification,总结如下:
如何创建并显示Notification
创建通知需要两个比较重要的类:NotificationManager和Notification
- NotificationManager :NotificationManager类是一个Android系统的服务类,它用来管理所有的通知
- Notification :Notification 类用来定义状态栏通知的各种属性,比如图标、消息、显示通知时是否需要声音、震动等。
下面通过代码创建一个简单的通知
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
private void normal_notification() {
//TODO 1:获取NotificationManager 通知管理者:发送通知 取消通知
NotificationManager manager= (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
//TODO 2:创建构造者
Notification.Builder builder = new Notification.Builder(this);
//TODO 3:设置属性 setSamllIcon该属性必须设置
builder.setSmallIcon(R.mipmap.ic_launcher);//设置小图标
builder.setContentTitle("我是标题");
builder.setContentText("我是内容");
//其他属性
builder.setTicker("我是提示信息");
builder.setContentInfo("我是附加信息")
//设置跳转其他页面
//1、创建意图对象
Intent intent= new Intent(this,OtherActivity.class);
//2、Intent对象转成PendingIntent
PendingIntent pendingIntent=PendingIntent.getActivity(this,100,intent,PendingIntent.FLAG_ONE_SHOT);
//3。设置跳转
builder.setContentIntent(pendingIntent);
//TODO 4:发送通知
//参数一 id 通知的id 参数二 通知对象
manager.notify(1,builder.build());
一个Notification必须设置以下内容:
- 状态栏的图标 :SmallIcon
- 标题和内容 :ContentTitle 和 ContentText
另外有一些可选的选项:
- 点击通知效果,是否跳页面
- 当通知来时,在status bar上滚动的内容
- 震动、声音、led灯的指示 等等
1. DEFAULT_ALL 使用所有默认值,比如声音,震动,闪屏等
2. DEFAULT_LIGHTS 使用默认闪光提示
3. DEFAULT_SOUNDS 使用默认提示声音
4. DEFAULT_VIBRATE 使用默认手机震动
自定义通知
1、 定义布局,如下:notification_layout.xml
这里用了两个ImageView 和TextView来显示通知的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/icon"
android:layout_width="60dp"
android:layout_height="match_parent"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@id/icon"
android:text="ABC"
android:textColor="#FF0000"
android:textSize="20sp" />
<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/icon"
android:layout_alignLeft="@id/title"
android:text="ABC"
android:textColor="#ffffff"
android:textSize="18sp" />
<ImageView
android:id="@+id/close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/video"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"/>
</RelativeLayout>
2、创建远程视图管理器
// 创建一个远程视图管理,
RemoteViews contentView = new RemoteViews(getApplication().getPackageName(),R.layout.notification_layout);
contentView.setTextViewText(R.id.title,contentTitle);
contentView.setTextViewText(R.id.content,contentText); // 设置文本框中显示的文本内容
contentView.setImageViewResource(R.id.icon,R.drawable.icon); // 设置图片视图
// 设置自定义布局中的点击监听
// 关闭的 Intent
Intent closeIntent = new Intent(this,MyService.class);
closeIntent.putExtra("close",1);
PendingIntent closePending = PendingIntent.getService(this,2,closeIntent,PendingIntent.FLAG_UPDATE_CURRENT);
contentView.setOnClickPendingIntent(R.id.close,closePending);
3 、将远程视图管理器设置到通知的内部布局上, 4.2 以上版本用 Builder 的 builder.setContent(contentView) 来设置
Notification.Builder builder = new Notification.Builder(this);
// 显示在状态栏上的小图标
builder.setSmallIcon(R.drawable.noti_icon);
// 添加状态栏上提示的文本 ( 显示一段时间就自动消失 )
builder.setTicker(ticker);
builder.setContent(contentView);
// 如果点击了内容部分,跳转到 Activity02 中
builder.setContentIntent(pIntent);
// 创建通知
notification = builder.build();
//低版本
notification.contentView = contentView;
4、具体代码如下:
private void showNotification(String ticker, String contentTitle, String contentText) {
Notification notification;
Intent it = new Intent(this, MainActivity.class);
//(Context对象,Intent的id,Intent对象,对Intent的更新方式)
//FLAG_UPDATE_CURRENT表示不销毁原来的PendingIntent,直接替换其中的Intent内容
//FLAG_CANCEL_CURRENT表示取消当前的PendingIntent,重新创建新的PendingIntent对象
PendingIntent pIntent = PendingIntent.getActivity(this, 0, it, PendingIntent.FLAG_UPDATE_CURRENT);
//创建一个远程视图管理
RemoteViews contentView = new RemoteViews(getApplication().getPackageName(), R.layout.notification_layout);
contentView.setTextViewText(R.id.title, contentTitle);
contentView.setTextViewText(R.id.content, contentText);//设置文本框中显示的文本内容
contentView.setImageViewResource(R.id.icon, R.drawable.icon);//设置图片视图
//设置自定义布局中的点击监听
//关闭的Intent,MusicService 进入onStartCommand中
Intent closeIntent = new Intent(this, MyService.class);
closeIntent.putExtra("close", 1);
PendingIntent closePdIntent = PendingIntent.getService(this, 2, closeIntent, PendingIntent.FLAG_UPDATE_CURRENT);
contentView.setOnClickPendingIntent(R.id.close, closePdIntent);
if (Build.VERSION.SDK_INT >= 16) {
Notification.Builder builder = new Notification.Builder(this);
//显示在状态栏上的小图标
builder.setSmallIcon(R.drawable.icon);
//显示在状态栏上的提示文本(显示一段时间消失)
builder.setTicker(ticker);
// //下拉看到的内容标题和文本
// builder.setContentTitle(contentTitle);
// builder.setContentText(contentText);
// //通知时间
// builder.setWhen(System.currentTimeMillis());
builder.setContent(contentView);
//如果点击了内容部分,跳转到Activity01界面
builder.setContentIntent(pIntent);
//创建通知
notification = builder.build();
} else {
notification = new Notification(R.drawable.icon, ticker, System.currentTimeMillis());
notification.contentIntent = pIntent;
notification.contentView = contentView;
}
//自动取消(当通知被点击时,系统会移除通知)
notification.flags = notification.FLAG_AUTO_CANCEL;
notification.defaults = Notification.DEFAULT_ALL;
// 显示通知
nm.notify(555, notification);
}
//第一次启动服务,服务创建成功时触发
@Override
public void onCreate() {
Log.e("m_tag", "=====onCreate======");
super.onCreate();
//获取通知管理器
nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
showNotification("这是一个通知", "1111111111111","222222222222222222");
}
//启动端和服务端的通讯入口
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("m_tag", "=====onStartCommand======");
if (intent != null && intent.hasExtra("oop")) {
int oop = intent.getIntExtra("close", 3);
if (oop == 1) {
//关闭
stopSelf();
}
}
return super.onStartCommand(intent, flags, startId);
}
//销毁服务时触发
@Override
public void onDestroy() {
Log.e("m_tag", "=====onDestroy======");
super.onDestroy();
nm.cancel(555);
}