通知是什麼?
通知為Notification,基本上是在應用程式的 UI 以外(通常是狀態列)顯示的訊息。
官網參考:https://developer.android.com/guide/topics/ui/notifiers/notifications?hl=zh-tw
如何使用通知
使用通知基本上有 4 個步驟
- 建立NotificationChannel
- 透過Builder建立通知並設定各種選項
- 設定通知要啟動的Action,該Action代表通知按下後要啟動哪個元件
- 透過NotificationManager發出通知
- 建立 NotificationChannel(NC)
NC的用途為分類並管理通知,在NC中可以設定一些通用項目讓屬於該NC的通知共用。
當裝置的android version在26或以上,必須設定NotificationChannel,否則會出現Toast提示錯誤訊息。
重點為建立NC時所指定的參數(NOTIFICATION_CHANNEL_ID )這個值在建立Notification時也必須設定,否則通知會無法顯示。
private static final String NOTIFICATION_CHANNEL_ID = "notification_channel";
private void createNotificationChannel() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "name",
NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("channel description");
channel.enableLights(true);
channel.setLightColor(Color.GREEN);
channel.enableVibration(true);
// channel.setShowBadge(false);
// channel.setSound(System.ALARM_ALERT);
mNotificationManager.createNotificationChannel(channel);
}
}
- 透過NotificationCompat.Builder建立通知並設定各種選項
a.透過NotificationCompat.Builder建立通知,最少必須包含一個小圖示,一個標題,一段文字。
Builder builder = new Builder(mContext, NOTIFICATION_CHANNEL_ID);
builder.setSmallIcon(android.R.drawable.sym_action_chat);
builder.setContentTitle(title);
builder.setContentText(text);
b.如果想設定更多的選項也是透過setxxx來達到,如下的設定就能讓該通知具有Heads-up的外觀,也就是在小型浮動視窗中出現。
builder.setPriority(NotificationCompat.PRIORITY_HIGH);
builder.setVibrate(new long[]{0, 1000});
builder.setAutoCancel(true);
- 設定通知要啟動的Action,該Action代表按下通知後要啟動哪個元件
Action是透過PendingIntent來設定如下
Intent actionIntent = new Intent(mContext, NotificationLaunchActivity.class);
PendingIntent launchNotificationLaunchActivity = PendingIntent
.getActivity(mContext, 0, actionIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(launchNotificationLaunchActivity);
Intent actionIntent = new Intent(mContext, NotificationLaunchActivity.class);
設定點擊該通知要啟動的Activity。
PendingIntent launchNotificationLaunchActivity = PendingIntent
.getActivity(mContext, 0, actionIntent, PendingIntent.FLAG_UPDATE_CURRENT);
包裝actionIntent的PendingIntent。
最後透過setContentIntent設定要啟動的Intent。
builder.setContentIntent(launchNotificationLaunchActivity);
注意:PendingIntent也可以啟動Service或BroadcastReceiver,使用以下方法來指定要啟動的元件。
PendingIntent.getBroadcast();
PendingIntent.getService()
- 透過NotificationManager發出通知
mNotificationManager.notify(NOTIFICATION_ID, builder.build());
NOTIFICATION_ID
為識別該通知的數值,但不太需要特別設定。
完整程式碼
public class NotificationWrapper {
public static final int NOTIFICATION_ID = 888;
private static final String NOTIFICATION_CHANNEL_ID = "notification_channel";
public static final String DIRECT_REPLY_BUTTON_KEY = "direct_reply_button_key";
private final Context mContext;
private NotificationManager mNotificationManager;
public NotificationWrapper(Context context) {
mContext = context;
mNotificationManager = (NotificationManager) mContext
.getSystemService(mContext.NOTIFICATION_SERVICE);
}
private void createNotificationChannel() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "name",
NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("channel description");
channel.enableLights(true);
channel.setLightColor(Color.GREEN);
channel.enableVibration(true);
// channel.setShowBadge(false);
// channel.setSound(System.ALARM_ALERT);
mNotificationManager.createNotificationChannel(channel);
}
}
private Builder createNotification(String title, String text) {
Builder builder = new Builder(mContext, NOTIFICATION_CHANNEL_ID);
builder.setSmallIcon(android.R.drawable.sym_action_chat);
builder.setContentTitle(title);
builder.setContentText(text);
builder.setPriority(NotificationCompat.PRIORITY_HIGH);
builder.setVibrate(new long[]{0, 1000});
builder.setAutoCancel(true);
setBadge(builder);
setContentIntent(builder);
return builder;
}
private void setBadge(Builder builder) {
builder.setNumber(100);
builder.setBadgeIconType(NotificationCompat.BADGE_ICON_LARGE);
}
@Deprecated
private void addDirectReplyButton(Builder builder) {
RemoteInput remoteInput = new RemoteInput.Builder(DIRECT_REPLY_BUTTON_KEY)
.setLabel("label")
.build();
int requestCode = 999;
Intent actionIntent = new Intent(mContext, MyBroadcastReceiver.class);
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(mContext,
requestCode,
actionIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action action =
new NotificationCompat.Action.Builder(android.R.drawable.sym_action_chat,
"direct reply action title", replyPendingIntent)
.addRemoteInput(remoteInput)
.build();
builder.addAction(action);
}
private void setContentIntent(Builder builder) {
Intent actionIntent = new Intent(mContext, NotificationLaunchActivity.class);
PendingIntent launchNotificationLaunchActivity = PendingIntent
.getActivity(mContext, 0, actionIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(launchNotificationLaunchActivity);
}
public void showNotification(String title, String text) {
createNotificationChannel();
Builder builder = createNotification(title, text);
mNotificationManager.notify(NOTIFICATION_ID, builder.build());
}
}
使用 NotificationWrapper來發送通知。
new NotificationWrapper(this).showNotification("this is notification title", "this is notification text");

以上是最基本的通知發送範例,下方則是介紹一些進階功能
進階功能
加入動作按鈕
加入動作按鈕和加入設定通知要啟動的Action類似。也是建立PendingIntent,並在其內加入要啟動的元件,最後透過addAction來加入。
需要注意的是動作按鈕最多只有3個,超過3個會忽略。
private void addActionButton(Builder builder) {
Intent actionIntent = new Intent(mContext, NotificationActionActivity.class);
PendingIntent launchNotificationActionActivity =
PendingIntent.getActivity(mContext, 0, actionIntent, 0);
builder.addAction(android.R.drawable.sym_action_call, "Launch", launchNotificationActionActivity);
}
加入動作按鈕後,點擊該按鈕便會啟動指定的元件(NotificationActionActivity)。

後續還有多種通知形式可以使用,如加入直接回應按鈕等等
範例可參考
https://github.com/googlesamples/android-Notifications
以及官方教學
https://developer.android.com/guide/topics/ui/notifiers/notifications?hl=zh-tw