在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
* <p>
* 封装通知栏实现,对于某些相关属性的处理逻辑,可根据具体的需求调整完善
*/
public class NotifyManager {
private static final String TAG = NotifyManager.class.getSimpleName();
private static NotifyManager sInstance = null;
private static NotificationManager mNotificationManager;
private static List<NotificationChannelGroup> mChannelGroupList;
/**
* 通知栏的消息对象的自增Id
*/
private AtomicInteger mInitialNotifyId = new AtomicInteger(0);
/**
* 全局通知栏的Id,不同消息对象,对应自身唯一的全局Id
*/
private volatile Map<Object, Integer> mGlobalNotifyIdMap;
private static Context mContext;
private NotifyManager() {
}
public static NotifyManager getInstance(Context context) {
if (sInstance == null) {
synchronized (NotifyManager.class) {
if (sInstance == null) {
sInstance = new NotifyManager();
mContext = context.getApplicationContext();
if (mNotificationManager == null) {
mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
initNotifyChannel();
}
}
}
}
return sInstance;
}
private static void initNotifyChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (mChannelGroupList == null) {
mChannelGroupList = new ArrayList<>();
}
mChannelGroupList.add(new NotificationChannelGroup(mContext.getResources().getString(R.string.groupId_001), "系统消息"));
mChannelGroupList.add(new NotificationChannelGroup(mContext.getResources().getString(R.string.groupId_002), "IM消息"));
mNotificationManager.createNotificationChannelGroups(mChannelGroupList);
NotificationChannel channel1 = new NotificationChannel(mContext.getResources().getString(R.string.channel_001), "系统消息", NotificationManager.IMPORTANCE_HIGH);
NotificationChannel channel2 = new NotificationChannel(mContext.getResources().getString(R.string.channel_002), "IM消息", NotificationManager.IMPORTANCE_HIGH);
channel1.setGroup(mContext.getResources().getString(R.string.groupId_001));
channel2.setGroup(mContext.getResources().getString(R.string.groupId_002));
mNotificationManager.createNotificationChannel(channel1);
mNotificationManager.createNotificationChannel(channel2);
}
}
public int getInitialNotifyId() {
if (mInitialNotifyId != null) {
return mInitialNotifyId.intValue();
}
return 0;
}
public Map<Object, Integer> getGlobalNotifyIdMap() {
return mGlobalNotifyIdMap;
}
/**
* IM消息的key的形式:key = "ImMessage"
*
* @param key
* @return 返回对应的id
*/
public int initNotifyId(Object key) {
Log.d(TAG, "method:initNotifyId#key=" + key);
if (mGlobalNotifyIdMap == null) {
mGlobalNotifyIdMap = new HashMap<>();
}
Integer notifyId = mGlobalNotifyIdMap.get(key);
Log.d(TAG, "method:initNotifyId#mGlobalNotifyIdMap=" + mGlobalNotifyIdMap);
Log.d(TAG, "method:initNotifyId#notifyId=" + notifyId);
if (notifyId == null) {
return putNotifyId(key);
} else {
return notifyId;
}
}
/**
* 保证每次往集合{@link #mGlobalNotifyIdMap}中put新值时,ID都是自增的
* <p>
* IM消息的key的形式:key = "ImMessage"
*
* @param key
* @return
*/
private int putNotifyId(Object key) {
Log.d(TAG, "method:putNotifyId#key=" + key);
if (mGlobalNotifyIdMap != null) {
int value = mInitialNotifyId.incrementAndGet();
Log.d(TAG, "method:putNotifyId#mInitialNotifyId.incrementAndGet#value=" + value);
mGlobalNotifyIdMap.put(key, value);
Log.d(TAG, "method:putNotifyId#mGlobalNotifyIdMap=" + mGlobalNotifyIdMap);
return value;
}
return 0;
}
private void notify(Object key, BaseNotifyBuilder builder) {
int notifyId = initNotifyId(key);
mNotificationManager.notify(notifyId, builder.build(mContext));
}
public NotificationManager getNotificationManager() {
return mNotificationManager;
}
public List<NotificationChannelGroup> getChannelGroupList() {
return mChannelGroupList;
}
public void showDefaultNotification(Object key, DefaultNotifyBuilder defaultBuilder) {
BaseNotifyBuilder builder = new BaseNotifyBuilder(defaultBuilder);
notify(key, builder);
}
public void showProgressNotification(Object key, int progress, int max, boolean interminate, DefaultNotifyBuilder defaultBuilder) {
ProgressNotifyBuilder builder = new ProgressNotifyBuilder(defaultBuilder);
notify(key, builder);
}
public void showLargeIconNotification(Object key, int largeIconId, DefaultNotifyBuilder defaultBuilder) {
LargeIconNotifyBuilder builder = new LargeIconNotifyBuilder(defaultBuilder).setLargeIcon(largeIconId);
notify(key, builder);
}
public void showBigTextNotification(Object key, String bigText, DefaultNotifyBuilder defaultBuilder) {
BigTextNotifyBuilder builder = new BigTextNotifyBuilder(defaultBuilder).setBigText(bigText);
notify(key, builder);
}
// ……………… 根据需要完善其它通知栏样式 ………………
}
其它样式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();
}
}
由于作者水平有限,语言描述及代码实现中难免有纰漏,望各位看官多提宝贵意见!
Hello , World !
感谢所有!