Android基础之Notification通知 | PendingIntent | 带源码

简介

  • 通知是Android系统中比较有特色的功能,当某个应用程序希望向用户发出一些提示信息,而该应用程序又不在前台运行时,就可以借助通知来实现
  • 既可以在活动里创建,又可以在广播接收器里创建,还可以在服务里创建
  • 首先需要一个NotificationManager来对通知进行管理,可以调用Context的getSystemService()方法获取到
  • getSystemService()方法接收一个字符串参数用于确定获取系统的哪个服务,我们传入Context.NOTIFICATION_SERVICE即可
NotificationManager manager = getSystemService(Context.NOTIFICATION_SERVICE);
  • 接下来使用BUilder构造器来创建Notification对象

setContentTitle():用于指定通知的标题内容,下拉系统状态栏就可以看到这部分内容

setContentText():用于指定通知的正文内容,同上

setWhen():用于指定通知被创建的时间,以毫秒为单位,当下拉状态栏时,这里指定的时间会显示在相应的通知上

setSmallIcon():用于设置通知的小图标,注意只能使用纯alpha图层的图片进行设置,小图标会显示在状态栏上

setLargeIcon():用于设置通知的大图标,当下拉系统状态栏时,就可以看见

Notification notification = new NotificationCompat.Builder(context)
	.setContentTitle("This is content title")
	.setContentText("This is content text")
	.setWhen(System.currentTimeMillis())
	.setSmallIcon(R.drawable.small_icon)
	.setLargeIcon(BitmapFactory.decodeResource(getResource(),R.drawable.large_icon))
	.build();
  • 然后调用NotificationManager的notify方法就可以将通知显示出来

notify()接收两个参数,第一个参数id,要保证每个通知指定的id都不一样,第二个参数Notification对象

manager.notify(1,notification);

实例

  • 修改xml
<Button
	        android:id="@+id/send_notice"
	        android:layout_width="261dp"
	        android:layout_height="56dp"
	        android:text="@string/send_notice"
	        android:onClick="sendNotice"
	        app:layout_constraintBottom_toBottomOf="parent"
	        app:layout_constraintEnd_toEndOf="parent"
	        app:layout_constraintStart_toStartOf="parent"
	        app:layout_constraintTop_toTopOf="parent"
	        app:layout_constraintVertical_bias="0.342" />
  • 修改MainActivity
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void sendNotice(View view) {

        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        Notification notification = null;

        //以下两者都可以显示通知
        //但是必须设置channelId
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            NotificationChannel notificationChannel = new NotificationChannel("1","my_channel", NotificationManager.IMPORTANCE_LOW);
            manager.createNotificationChannel(notificationChannel);

            notification = new Notification.Builder(this)
                .setContentTitle("This is content title")
                .setContentText("This is content text")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
                .setChannelId("1")
                .build();

        } else {
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setContentTitle("This is content title")
                .setContentText("This is content text")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
                .setChannelId("1");

            notification = notificationBuilder.build();

        }
        manager.notify(1,notification);
    }

}

创建完成之后,会显示通知内容,但是无法点击

  • 新建NotificationActivity,修改其xml
<TextView
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:text="@string/this_is_notification_layout"
	        android:textSize="24sp"
	        android:gravity="center"
	        app:layout_constraintBottom_toBottomOf="parent"
	        app:layout_constraintEnd_toEndOf="parent"
	        app:layout_constraintStart_toStartOf="parent"
	        app:layout_constraintTop_toTopOf="parent" />
  • 修改MainActivity
public void sendNotice(View view) {

    //用于实现点击通知跳转
    Intent intent = new Intent(this,NotificationActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,0);

    NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    Notification notification = null;

    //以下两者都可以显示通知
    //但是必须设置channelId
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

        NotificationChannel notificationChannel = new NotificationChannel("1","my_channel", NotificationManager.IMPORTANCE_LOW);
        manager.createNotificationChannel(notificationChannel);

        notification = new Notification.Builder(this)
            .setContentTitle("This is content title")
            .setContentText("This is content text")
            .setWhen(System.currentTimeMillis())
            .setSmallIcon(R.mipmap.ic_launcher)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
            .setChannelId("1")
            .setContentIntent(pendingIntent)
            .build();

    } else {
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
            .setContentTitle("This is content title")
            .setContentText("This is content text")
            .setWhen(System.currentTimeMillis())
            .setSmallIcon(R.mipmap.ic_launcher)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
            //用于设置版本号
            .setChannelId("1")
            //用于点击跳转
            .setContentIntent(pendingIntent);

        notification = notificationBuilder.build();

    }
    manager.notify(1,notification);
}
  • 点击后取消状态栏的通知标识的两种方法

第一种,在NotificationCompat.Builder中连缀一个setAutoCancel方法

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                    .setContentTitle("This is content title")
                    .setContentText("This is content text")
                    .setWhen(System.currentTimeMillis())
                    .setSmallIcon(R.mipmap.ic_launcher)
                 .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
                    //用于设置版本号
                    .setChannelId("1")
                    //用于点击跳转
                    .setContentIntent(pendingIntent)
                    //用于通知点击后自动消失
                    .setAutoCancel(true);

第二种,(在跳转界面)显示调用NotificationManager的cancel方法取消,参数是通知的id

NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.cancel(1);
  • 源码地址

DoSomeAndroidTest/NotificationTest at main · qricis/DoSomeAndroidTest · GitHub

更多功能

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

    //构建NotificationChannel实例
    NotificationChannel notificationChannel = new NotificationChannel("1","my_channel", NotificationManager.IMPORTANCE_LOW);

    //设置通知出现时的闪光灯
    notificationChannel.enableLights(true);
    notificationChannel.setLightColor(Color.GREEN);

    //设置通知出现时的震动
    notificationChannel.enableVibration(true);
    notificationChannel.setVibrationPattern(new long[]{0,1000,1000,1000});

    notificationChannel.setSound(Uri.fromFile(new File("/system/media/audio/notifications/DearDeer.ogg")),Notification.AUDIO_ATTRIBUTES_DEFAULT);
    //在notificationManager中创建通知渠道
    manager.createNotificationChannel(notificationChannel);

    notification = new Notification.Builder(this)
        .setContentTitle("This is content title")
        .setContentText("Learn how to build notifications,send and sync data,and use voice actions.Get the official Android IDE and developer tools to build apps for Android")
        .setWhen(System.currentTimeMillis())
        .setSmallIcon(R.mipmap.ic_launcher)
        .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
        .setChannelId("1")
        .setContentIntent(pendingIntent)
        .setAutoCancel(true)
        .setStyle(new Notification.BigTextStyle().bigText("Learn how to build notifications,send and sync data,and use voice actions.Get the official Android IDE and developer tools to build apps for Android"))
        .setStyle(new Notification.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(getResources(),R.drawable.head)))
        .setPriority(Notification.PRIORITY_MAX)
        .build();

} else {
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
        .setContentTitle("This is content title")
        .setContentText("This is content text")
        .setWhen(System.currentTimeMillis())
        .setSmallIcon(R.mipmap.ic_launcher)
        .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
        //用于设置版本号
        .setChannelId("1")
        //用于点击跳转
        .setContentIntent(pendingIntent)
        //用于通知点击后自动消失
        .setAutoCancel(true)
        //接收一个Uri参数,在通知发出的时候播放一段音频
        .setSound(Uri.fromFile(new File("/system/media/audio/notifications/DearDeer.ogg")))
        //设置震动(静止时长,振动时长,静止时长,振动时长),但需要申请权限
        .setVibrate(new long[]{0,1000,1000,1000})
        //设置锁屏时闪烁灯(颜色,亮起时长,暗去时长)
        .setLights(Color.GREEN,1000,1000)
        //直接使用默认效果
        .setDefaults(Notification.DEFAULT_ALL)
        //将通知内容显示完整
        .setStyle(new NotificationCompat.BigTextStyle().bigText("Learn how to build notifications,send and sync data,and use voice actions.Get the official Android IDE and developer tools to build apps for Android"))
        //通知里显示一张大图片
        .setStyle(new NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_background)))
        //设置通知的重要程度,5个常量可选(_DEFAULT/_MIN/_LOW/_HIGH/_MAX)
        //默认和不设置效果一样,最低只会在特定场景显示,较低会将这类通知缩小或改变显示顺序,较高将之放大或改变顺序,最高让用户立刻看到,甚至做出响应操作
        .setPriority(NotificationCompat.PRIORITY_MAX)
        ;
    notification = notificationBuilder.build();

}

PendingIntent

  • 和Intent类似,都可以用于启动活动、启动服务以及发送广播等,不同的是,Intent更倾向于立即去执行某个动作,而PendingIntent更加倾向于在某个合适的时机去执行某个动作
  • 所以可以把PendingIntent理解成延迟执行的Intent
  • 它提供几个静态方法用于获取PendingIntent实例(getActivity()/getBroadcast()/getService())
  • 第一个参数依旧是context,第二个参数一般用不上,传入0,第三个参数是一个Intent对象,可以通过这个对象构建出PendingIntent的"意图",第四个参数用于确定PendingIntent的行为(FLAG_ONE_SHOT/FLAG_NO_CREATE/FLAG_CANCEL_CURRENT/FLAG_UPDATE_CURRENT),通常传入0
  • NotificationCompat.Builder可以连缀一个setContentIntent()方法,接收的参数正好是PendingIntent对象
上一篇:聊一聊Yarp结合Nacos完成服务发现


下一篇:sprint-boot 通过 jackson,Gson,fastjson输出json格式数据