Android自定义通知

1.Notification简单概述

通知是 Android 在您的应用 UI 之外显示的消息,用于向用户提供提醒、来自其他人的通信或来自您的应用的其他及时信息。用户可以点击通知打开您的应用或直接从通知中执行操作。

2. 代码实现

2.1 页面搭建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#FFF0FF"
tools:context=".MainActivity">

<TextView
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="#FF00F0"
android:gravity="center"
android:text="自定义通知"
android:textSize="40dp" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:orientation="horizontal">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="通知渠道:"
android:textSize="30dp" />

<Spinner
android:id="@+id/nfChannel"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:padding="20dp"
android:layout_height="wrap_content">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="通知标题:"
android:textSize="30dp" />

<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:id="@+id/nfTitle"/>

</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:padding="20dp"
android:layout_height="wrap_content">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="通知内容:"
android:textSize="30dp" />

<EditText
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#FFFFFF"
android:id="@+id/nfContent"/>
</LinearLayout>

<Button
android:id="@+id/sendBtn"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_margin="50dp"
android:text="推送通知"/>
</LinearLayout>

image-20241113124321516

点击通知转跳到消息详情

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFF0FF"
android:orientation="vertical">

<TextView
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="#FF00F0"
android:gravity="center"
android:text="通知内容"
android:textSize="40dp" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp">


<EditText
android:id="@+id/msgTitle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:textSize="30dp" />

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp">

<EditText
android:id="@+id/msgContent"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#FFFFFF"
android:textSize="30dp" />
</LinearLayout>

<Button
android:id="@+id/returnBtn"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_margin="50dp"
android:text="返回" />
</LinearLayout>

1731473054373.png

3. 功能实现

MainActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package com.example.notificationmanger;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MainActivity extends AppCompatActivity {

// UI 组件
Spinner nfSpinner; // 用于选择通知重要性级别的 Spinner
EditText nfTitle; // 输入通知标题的 EditText
EditText nfContent; // 输入通知内容的 EditText
Button sendBtn; // 发送通知的按钮

// 存储通知类型的列表
List<String> noticeList;

// 通知的渠道 ID
String[] channelIds = {
"notificationDemo1",
"notificationDemo2",
"notificationDemo3",
"notificationDemo4",
"notificationDemo5"
};

// 通知渠道的重要性级别
int[] notificationImportance = {
NotificationManager.IMPORTANCE_NONE,
NotificationManager.IMPORTANCE_MIN,
NotificationManager.IMPORTANCE_LOW,
NotificationManager.IMPORTANCE_DEFAULT,
NotificationManager.IMPORTANCE_HIGH
};

// 创建通知的方法
private Notification createNotification(NotificationManager manager, String channelId, String title, String content) {
// 构建通知
Notification.Builder builder = new Notification.Builder(this, channelId);

// 点击通知时打开 MsgActivity 的 Intent
Intent cIntent = new Intent(this, MsgActivity.class);
Bundle bundle = new Bundle();
bundle.putString("title", title); // 将标题传递给 MsgActivity
bundle.putString("content", content); // 将内容传递给 MsgActivity
cIntent.putExtras(bundle);

// 创建通知的 PendingIntent
PendingIntent pIntent = PendingIntent.getActivity(this, 0, cIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);

// 设置通知的属性
builder.setContentTitle(title)
.setContentText(content)
.setSmallIcon(R.drawable.small) // 通知的小图标
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.small)) // 通知的大图标
.setAutoCancel(true) // 点击后自动取消通知
.setUsesChronometer(true) // 显示计时器格式的时间
.setContentIntent(pIntent); // 设置点击通知时的 Intent

// 从 Spinner 中获取所选项并设置为副文本
int index = nfSpinner.getSelectedItemPosition();
builder.setSubText(noticeList.get(index));

return builder.build(); // 返回构建好的通知
}

// 发送按钮的监听器
View.OnClickListener sendBtnListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
// 获取 NotificationManager
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = null;
int index = nfSpinner.getSelectedItemPosition(); // 获取 Spinner 中所选的索引

// 如果是 Android Oreo 或更高版本,创建通知渠道
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
channel = manager.getNotificationChannel(channelIds[index]);
// 如果渠道不存在,则创建它
if (channel == null) {
channel = new NotificationChannel(channelIds[index], "新渠道", notificationImportance[index]);
manager.createNotificationChannel(channel);
}
}

// 从 EditText 获取标题和内容
String content = nfContent.getText().toString().trim();
String title = nfTitle.getText().toString().trim();

// 检查标题和内容是否为空
if (content.isEmpty() || title.isEmpty()) {
Toast.makeText(MainActivity.this, "请输入通知标题和内容!", Toast.LENGTH_SHORT).show();
return; // 如果验证失败,则退出
}

// 创建并发送通知
Notification notification = createNotification(manager, channelIds[index], title, content);
Random random = new Random();
manager.notify(random.nextInt(1000), notification); // 使用随机 ID 发送通知
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // 设置活动的布局
findViews(); // 初始化 UI 组件

// 初始化通知类型列表
noticeList = new ArrayList<>();
noticeList.add("不重要通知");
noticeList.add("最低的通知");
noticeList.add("稍微重要的通知");
noticeList.add("默认通知");
noticeList.add("重要通知");

// 使用 ArrayAdapter 设置 Spinner
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, noticeList);
nfSpinner.setAdapter(adapter);

// 设置按钮的点击监听
sendBtn.setOnClickListener(sendBtnListener);
}

// 查找并初始化 UI 组件的方法
private void findViews() {
nfSpinner = findViewById(R.id.nfChannel);
nfTitle = findViewById(R.id.nfTitle);
nfContent = findViewById(R.id.nfContent);
sendBtn = findViewById(R.id.sendBtn);
}
}

MsgActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.example.notificationmanger;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;

public class MsgActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// 启用边缘到边缘模式,使活动全屏显示
EdgeToEdge.enable(this);

// 设置活动的布局
setContentView(R.layout.activity_msg);

// 获取从通知传递过来的 Intent
Intent intent = getIntent();

// 从 Intent 中提取标题和内容
String content = intent.getStringExtra("content");
String title = intent.getStringExtra("title");

// 获取用于显示内容和标题的 TextView
TextView msgContent = (TextView) findViewById(R.id.msgContent);
TextView msgTitle = (TextView) findViewById(R.id.msgTitle);

// 设置 TextView 的文本
msgContent.setText(content);
msgTitle.setText(title);

// 获取返回按钮并设置点击监听器
Button returnBtn = (Button) findViewById(R.id.returnBtn);
returnBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 点击返回按钮时结束当前活动
finish();
}
});
}
}

4. 通知的结构

1731473213954.png

小图标:此为必要图标,通过 setSmallIcon() 设置。
应用名称:此由系统提供。
时间戳:此由系统提供,不过您可以通过 setWhen() 进行替换,或使用 setShowWhen(false) 将其隐藏。
大图标:此为可选图标(通常仅用于联系人照片;请勿将其用于应用图标),通过 setLargeIcon() 设置。
标题:此为可选内容,通过 setContentTitle() 设置。
文本:此为可选内容,通过 setContentText() 设置。

4.1 关键类

  1. NotificationManager 通知管理器,用来发起、更新、删除通知
  2. NotificationChannel 通知渠道,8.0及以上配置渠道以及优先级
  3. NotificationCompat.Builder 通知构造器,用来配置通知的布局显示以及操作相关

5. 消息类型分类

Android通知Notification使用全解析,看这篇就够了_android notification-CSDN博客

在这里插入图片描述