基本概念
Android 通知(Notification)是应用向用户显示重要信息的标准化方式,即使应用未运行也能提醒用户。
基本用法
1.调用Context的getSystemService得到NotificationManager管理通知
NotificationManager manager=(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
2.使用Builder构造器创建Notification对象(使用support库中的NotificationCompat类的构造器创建Notification对象,保证兼容性)
Notification notification=new NotificationCompat.Builder(context).build();
3.在build之前连缀任意多的设置方法
Notification notification=new NotificationCompat.Builder(context).
setContentTitle("content title").
setContentText("content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher_background)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_foreground))
.build();
setContentTitle("content title"):设置通知的标题内容 setContentText("content text"):设置通知的正文内容 setWhen(System.currentTimeMillis())指定通知被创建的时间,以毫秒为单位 setSmallIcon:用于设置通知的小图标,小图标会显示在系统通知栏上 setLargeIcon:设置通知的大图标,当下拉系统通知栏时就可以看到设置的大图标
4.调用NotificationManager的notify方法可以让通知显示出来
manager.notify(1,notification);
接收两个参数,id和Notification对象
在 Android 13(API 33) 或更高版本中,应用必须声明并动态申请
POST_NOTIFICATIONS
权限才能向用户显示通知。
public class MainActivity extends AppCompatActivity {
private static final String CHANNEL_ID = "default_channel";
private static final int NOTIFICATION_ID = 1;
private static final int REQUEST_CODE_POST_NOTIFICATIONS = 100;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
Button sendNotice=(Button)findViewById(R.id.send);
sendNotice.setOnClickListener(this::onClick);
Context context=MainActivity.this;
// createNotificationChannel();
}
public void onClick(View v){
if(R.id.send==v.getId()){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
== PackageManager.PERMISSION_GRANTED) {
sendNotification();
} else {
// 请求通知权限
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.POST_NOTIFICATIONS},
REQUEST_CODE_POST_NOTIFICATIONS);
}
} else {
// Android 12 及以下直接发送通知
sendNotification();
}
}
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE_POST_NOTIFICATIONS) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
sendNotification();
} else {
Toast.makeText(this, "通知权限被拒绝", Toast.LENGTH_SHORT).show();
}
}
}
private void sendNotification() {
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Content Title")
.setContentText("Content Text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher_background)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.build();
manager.notify(NOTIFICATION_ID, notification);
}
}
设置通知点击效果
使用PendingIntent,可以用于启动活动、服务以及发送广播,可以简单理解为延迟执行的Intent
提供静态方法获取PendingIntent的实例
getActivity getBroadcast getService 接收的参数相同:第一个参数Context,第二个参数一般传入0,第三个参数Intent,第四个参数确定PendingIntent的行为,FLAG_ONE_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT、FLAG_UPDATE_CURRENT,通常传入0
通过NotificationCompat.Builder构造器连缀setContentIntent方法,接收参数为PendingIntent对象,设置相应的逻辑
在 Android 12(API 31)及以上版本中,创建
PendingIntent
时必须显式指定FLAG_IMMUTABLE
或FLAG_MUTABLE
标志。
FLAG_IMMUTABLE
(推荐):创建的PendingIntent
不可修改
FLAG_MUTABLE
:允许修改(仅当需要动态更新时才使用)
private void sendNotification() {
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent=new Intent(this, NotificationActivity.class);
PendingIntent pi=PendingIntent.getActivity(this,0,intent, PendingIntent.FLAG_IMMUTABLE);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Content Title")
.setContentText("Content Text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher_background)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pi)
.build();
manager.notify(NOTIFICATION_ID, notification);
}
设置点击后取消通知图标
1.在NotificationCompat.Builder中连缀一个setAutoCancel方法,传入true表示点击了这个通知后通知会自动取消
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Content Title")
.setContentText("Content Text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher_background)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pi)
.setAutoCancel(true)
.build();
2.显示调用NotificationManager的cancel方法
在跳转后的Activity中显示调用cancel方法
public class NotificationActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_notification);
NotificationManager manager=(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.cancel(1);
}
}
cancel中的参数代表该通知的id
通知的API
setSound:在通知发出时播放一段音频,接收Uri参数,在指定音频文件时要获取指定音频文件的URI
private void sendNotification() {
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent=new Intent(this, NotificationActivity.class);
PendingIntent pi=PendingIntent.getActivity(this,0,intent, PendingIntent.FLAG_IMMUTABLE);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Content Title")
.setContentText("Content Text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher_background)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pi)
.setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Luna.ogg")))
.build();
manager.notify(NOTIFICATION_ID, notification);
}
setVibrate:在通知到来时让手机震动,使用vibrate属性,是一个长整型的数组,用于设置手机静止和振动的时长,以毫秒为单位,数组元素交替表示手机静止和振动的时长
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Content Title")
.setContentText("Content Text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher_background)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pi)
.setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Luna.ogg")))
.setVibrate(new long[]{0,100,100,1000})
.build();
<uses-permission android:name="android.permission.VIBRATE" />
setDefaults:直接使用通知的默认效果
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Content Title")
.setContentText("Content Text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher_background)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pi)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.build();
高级功能
setStyle:构建富文本的通知信息,接收NotificationCompat.Style参数,这个参数用来构建具体的富文本信息
.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_background))) 创建了NotificationCompat.BigPictureStyle()对象,用于设置大图片,然后调用bigPicture方法传入图片,通过BitmapFactory.decodeResource方法将图片解析成Bitmap对象再传入bigPicture方法
.setStyle(new NotificationCompat.BigTextStyle().bigText("ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg")) 创建了NotificationCompat.BigTextStyle()对象,用于封装长文字信息,调用bigText方法将文字内容传入
setPriority:用于设置通知的重要程度,接受一个整型参数用于设置这条通知的重要程度,PRIORITY_DEFAULT表示默认的重要程度,PRIORITY_MIN表示最低的重要程度,只在用户下拉状态栏时显示;PRIORITY_LOW表示较低的重要程度;PRIORITY_HIGH表示较高的重要程度;PRIORITY_MAX表示最高的重要程度