【Android】通知
基本概念
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;
@Overrideprotected 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 {
@Overrideprotected 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表示最高的重要程度