在Android应用开发中我们经常会使用到通知栏的功能,安卓的通知栏有多种类型样式,包括基本类型、带进度条的类型、大图标类型、大段文本类型等,在Android 8.0 (API level 26) 中使用通知栏的代码示例:
// Create an explicit intent for an Activity in your app
Intent intent = new Intent(this, AlertDetails.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// Set the intent that will fire when the user taps the notification
.setContentIntent(pendingIntent)
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
// notificationId is a unique int for each notification that you must define
notificationManager.notify(notificationId, builder.build());
以下会对notification的使用做一个简单的封装,具体的功能逻辑还可以再扩展
先看一下具体的使用:
package com.windfallsheng.mynotificationmanager;
import android.app.PendingIntent;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.windfallsheng.mynotificationmanager.notification.DefaultNotifyBuilder;
import com.windfallsheng.mynotificationmanager.notification.NotifyManager;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private final String TAG = MainActivity.class.getSimpleName();
TextView tvImMsg, tvSysMsg;
private String userArray[] = {"Cyra", "Morgen", "Iris", "Mia"};
private String messageArray[] = {"我发表了新的美食文章", "我更新了我的相册", "我在FaceBook申请了账号", "我做了一个好看的小视频"};
private String sysMessageArray[] = {"有新的系统版本可以升级", "收到新的资讯内容", "为你推荐周边美食、娱乐活动", "最新最火爆的游戏"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvImMsg = findViewById(R.id.textview_im_msg);
tvSysMsg = findViewById(R.id.textview_sys_msg);
tvImMsg.setOnClickListener(this);
tvSysMsg.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.textview_im_msg:
notifyImMessage();
break;
case R.id.textview_sys_msg:
notifySysMessage();
break;
default:
break;
}
}
private void notifyImMessage() {
int uIndex = (int) (Math.random() * userArray.length);
int mIndex = (int) (Math.random() * messageArray.length);
String userName = userArray[uIndex];
String content = messageArray[mIndex];
String key = "ImMessage#" + userName;
int requestCode = NotifyManager.getInstance(MainActivity.this).initNotifyId(key);
Log.d(TAG, "method:notifyReceivedMessage#key=" + key + ", requestCode=" + requestCode);
Intent intent = new Intent(MainActivity.this, NotificationMsgActivity.class);
intent.putExtra("msgContent", userName + ":\n\n" + content);
PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
DefaultNotifyBuilder defaultNotifyBuilder = new DefaultNotifyBuilder(userName, content)
.setChannelId(getResources().getString(R.string.channel_001))
.setContentIntent(pendingIntent);
NotifyManager.getInstance(MainActivity.this).showDefaultNotification(key, defaultNotifyBuilder);
}
private void notifySysMessage() {
String key = "SysMessage#系统消息";
int mIndex = (int) (Math.random() * sysMessageArray.length);
String content = sysMessageArray[mIndex];
int requestCode = NotifyManager.getInstance(MainActivity.this).initNotifyId(key);
Log.d(TAG, "method:notifyReceivedMessage#key=" + key + ", requestCode=" + requestCode);
Intent intent = new Intent(MainActivity.this, NotificationMsgActivity.class);
intent.putExtra("msgContent", "系统消息" + ":\n\n" + content);
PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
DefaultNotifyBuilder defaultNotifyBuilder = new DefaultNotifyBuilder("系统消息", content)
.setChannelId(getResources().getString(R.string.channel_002))
.setContentIntent(pendingIntent);
NotifyManager.getInstance(MainActivity.this).showDefaultNotification(key, defaultNotifyBuilder);
}
}
DefaultNotifyBuilder中有一些参数会有默认值:
package com.windfallsheng.mynotificationmanager.notification;
import android.app.PendingIntent;
import android.support.v4.app.NotificationCompat;
import com.windfallsheng.mynotificationmanager.R;
/**
* @author lzsheng
*/
public class DefaultNotifyBuilder {
public String channelId;
public int smallIcon = R.drawable.ic_launcher_foreground;
public CharSequence contentTitle = "小蜗牛Tech";
public CharSequence contentText;
public CharSequence ticker;
public int flag = NotificationCompat.FLAG_AUTO_CANCEL;
public int priority = NotificationCompat.PRIORITY_HIGH;
public long when = System.currentTimeMillis();
public PendingIntent contentIntent;
public boolean autoCancel = true;
public boolean sound;
public boolean vibrate;
public boolean lights;
public DefaultNotifyBuilder(CharSequence contentText) {
this.contentText = contentText;
}
public DefaultNotifyBuilder(CharSequence contentTitle, CharSequence contentText) {
this.contentTitle = contentTitle;
this.contentText = contentText;
}
public DefaultNotifyBuilder(int smallIcon, CharSequence contentTitle, CharSequence contentText) {
this.smallIcon = smallIcon;
this.contentTitle = contentTitle;
this.contentText = contentText;
}
public DefaultNotifyBuilder setChannelId(String channelId) {
this.channelId = channelId;
return this;
}
public DefaultNotifyBuilder setTicker(CharSequence ticker) {
this.ticker = ticker;
return this;
}
public DefaultNotifyBuilder setFlag(int flag) {
this.flag = flag;
return this;
}
public DefaultNotifyBuilder setPriority(int priority) {
this.priority = priority;
return this;
}
public DefaultNotifyBuilder setWhen(long when) {
this.when = when;
return this;
}
public DefaultNotifyBuilder setContentIntent(PendingIntent contentIntent) {
this.contentIntent = contentIntent;
return this;
}
public DefaultNotifyBuilder setAutoCancel(boolean autoCancel) {
this.autoCancel = autoCancel;
return this;
}
public DefaultNotifyBuilder setSound(boolean sound) {
this.sound = sound;
return this;
}
public DefaultNotifyBuilder setVibrate(boolean vibrate) {
this.vibrate = vibrate;
return this;
}
public DefaultNotifyBuilder setLights(boolean lights) {
this.lights = lights;
return this;
}
}
BaseNotifyBuilder会对基本的参数进行组装:
package com.windfallsheng.mynotificationmanager.notification;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.NotificationCompat;
import android.text.TextUtils;
import android.util.Log;
/**
* @author lzsheng
*/
public class BaseNotifyBuilder {
private static final String TAG = BaseNotifyBuilder.class.getSimpleName();
protected DefaultNotifyBuilder defaultBuilder;
protected NotificationCompat.Builder notifyBuilder;
public BaseNotifyBuilder(@NonNull DefaultNotifyBuilder defaultBuilder) {
if (defaultBuilder == null) {
throw new IllegalArgumentException("defaultNotifyBuilder = null.");
}
this.defaultBuilder = defaultBuilder;
}
public Notification build(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notifyBuilder = new NotificationCompat.Builder(context, defaultBuilder.channelId);
} else {
notifyBuilder = new NotificationCompat.Builder(context);
}
Log.d(TAG, "method:build#defaultBuilder=" + defaultBuilder);
// 设置顶部状态栏的小图标
notifyBuilder.setSmallIcon(defaultBuilder.smallIcon);
// 设置通知中心的标题
notifyBuilder.setContentTitle(defaultBuilder.contentTitle);
// 设置通知中心中的内容
CharSequence contentText = defaultBuilder.contentText;
if (!TextUtils.isEmpty(contentText)) {
notifyBuilder.setContentText(defaultBuilder.contentText);
}
PendingIntent contentIntent = defaultBuilder.contentIntent;
if (contentIntent != null) {
notifyBuilder.setContentIntent(contentIntent);
}
int defaults = 0;
boolean sound = defaultBuilder.sound;
boolean vibrate = defaultBuilder.vibrate;
boolean lights = defaultBuilder.lights;
if (sound) {
defaults |= Notification.DEFAULT_SOUND;
}
if (vibrate) {
defaults |= Notification.DEFAULT_VIBRATE;
}
if (lights) {
defaults |= Notification.DEFAULT_LIGHTS;
}
if (defaults != 0) {
notifyBuilder.setDefaults(defaults);
}
CharSequence ticker = defaultBuilder.ticker;
if (!TextUtils.isEmpty(ticker)) {
notifyBuilder.setTicker(defaultBuilder.ticker);
}
notifyBuilder.setAutoCancel(defaultBuilder.autoCancel);
notifyBuilder.setWhen(defaultBuilder.when);
notifyBuilder.setPriority(defaultBuilder.priority);
return notifyBuilder.build();
}
}
MyNotificationManager采用单例模式
从 Android 8.0(API 级别 26)开始,必须为所有通知分配渠道,否则通知将不会显示。通过将通知归类为不同的渠道,用户可以停用您应用的特定通知渠道(而非停用您的所有通知),还可以控制每个渠道的视觉和听觉选项,所有这些操作都在 Android 系统设置中完成。用户还可以长按通知以更改所关联渠道的行为。
package com.windfallsheng.mynotificationmanager.notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import com.windfallsheng.mynotificationmanager.R;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author lzsheng
*
* 封装通知栏实现,对于某些相关属性的处理逻辑,可根据具体的需求调整完善
*/
public class NotifyManager {
private static final String TAG = NotifyManager.class.getSimpleName();
private static NotifyManager sInstance = null;
private static NotificationManager mNotificationManager;
private static List mChannelGroupList;
/**
* 通知栏的消息对象的自增Id
*/
private AtomicInteger mInitialNotifyId = new AtomicInteger(0);
/**
* 全局通知栏的Id,不同消息对象,对应自身唯一的全局Id
*/
private volatile Map
其它样式builder的处理逻辑,如 BigTextNotifyBuilder:
package com.windfallsheng.mynotificationmanager.notification;
import android.app.Notification;
import android.content.Context;
import android.support.v4.app.NotificationCompat;
/**
* @author lzsheng
*/
public class BigTextNotifyBuilder extends BaseNotifyBuilder{
public String mBigText;
public NotificationCompat.BigTextStyle mBigTextStyle;
public BigTextNotifyBuilder(DefaultNotifyBuilder defaultBuilder) {
super(defaultBuilder);
}
public BigTextNotifyBuilder setBigText(String bigText) {
this.mBigText = bigText;
mBigTextStyle = new NotificationCompat.BigTextStyle()
.bigText(bigText);
return this;
}
@Override
public Notification build(Context context) {
super.build(context);
notifyBuilder.setStyle(mBigTextStyle);
return notifyBuilder.build();
}
}
示例代码GitHub地址
由于作者水平有限,语言描述及代码实现中难免有纰漏,望各位看官多提宝贵意见!
Hello , World !
感谢所有!