Android Notification通知使用详解

 更新时间:2022年09月08日 08:56:19   作者:愿天深海  
消息通知(Notification)是Android系统中比较有特色的一个功能,当某个应用程序希望用户发出一些提示信息,而该应用又不在前台运行时,就可以借助通知来实现

在Android应用的开发中,必然会遇上通知的开发需求,本文主要讲一下Android中的通知 Notification的简单基本使用,主要包含创建通知渠道、初始化通知、显示通知、显示图片通知、通知点击、以及配合WorkManager发送延迟通知。

Demo下载

创建通知渠道

首先,创建几个常量和变量,其中渠道名是会显示在手机设置-通知里app对应展示的通知渠道名称,一般基于通知作用取名。

    companion object {
        //渠道Id
        private const val CHANNEL_ID = "渠道Id"
        //渠道名
        private const val CHANNEL_NAME = "渠道名-简单通知"
        //渠道重要级
        private const val CHANNEL_IMPORTANCE = NotificationManager.IMPORTANCE_DEFAULT
    }
    private lateinit var context: Context
    //Notification的ID
    private var notifyId = 100
    private lateinit var manager: NotificationManager
    private lateinit var builder: NotificationCompat.Builder

然后获取系统通知服务,创建通知渠道,其中因为通知渠道是Android8.0才有的,所以增加一个版本判断:

        //获取系统通知服务
        manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        //创建通知渠道,Android8.0及以上需要
        createChannel()
    private fun createChannel() {
        //创建通知渠道,Android8.0及以上需要
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            return
        }
        val notificationChannel = NotificationChannel(
            CHANNEL_ID,
            CHANNEL_NAME,
            CHANNEL_IMPORTANCE
        )
        manager.createNotificationChannel(notificationChannel)
    }

初始化通知

先生成NotificationCompat.Builder,然后初始化通知Builder的通用配置:

        builder = NotificationCompat.Builder(context.applicationContext, CHANNEL_ID)
        initNotificationBuilder()
    /**
     * 初始化通知Builder的通用配置
     */
    private fun initNotificationBuilder() {
        builder
            .setAutoCancel(true) //设置这个标志当用户单击面板就可以让通知自动取消
            .setSmallIcon(R.drawable.ic_reminder) //通知的图标
            .setWhen(System.currentTimeMillis()) //通知产生的时间,会在通知信息里显示
            .setDefaults(Notification.DEFAULT_ALL)
    }

此外builder还有setVibrate、setSound、setStyle等方法,按需配置即可。

显示通知

给builder设置需要通知需要显示的title和content,然后通过builder.build()生成生成通知Notification,manager.notify()方法将通知发送出去。

    fun configNotificationAndSend(title: String, content: String){
        builder.setContentTitle(title)
            .setContentText(content)
        val notification = builder.build()
        //发送通知
        manager.notify(notifyId, notification)
        //id自增
        notifyId++
    }

最简单的通知显示至此上面三步就完成了。

效果如下图:

显示图片通知

当通知内容过多一行展示不下时,可以通过设置

builder.setStyle(NotificationCompat.BigTextStyle().bigText(content)) //设置可以显示多行文本

这样通知就能收缩和展开,显示多行文本。

另外setStyle还可以设置图片形式的通知:

setStyle(NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(resources,R.drawable.logo)))//设置图片样式

效果如下图:

通知点击

目前为止的通知还只是显示,因为设置了builder.setAutoCancel(true),点击通知之后通知会自动消失,除此之外还没有其他操作。

给builder设置setContentIntent(PendingIntent)就能有通知点击之后的其他操作了。PendingIntent可以看作是对Intent的一个封装,但它不是立刻执行某个行为,而是满足某些条件或触发某些事件后才执行指定的行为。PendingIntent获取有三种方式:Activity、Service和BroadcastReceiver获取。通过对应方法PendingIntent.getActivity、PendingIntent.getBroadcast、PendingIntent.getService就能获取。

这里就示例一下PendingIntent.getBroadcast和PendingIntent.getActivity

PendingIntent.getBroadcast

首先创建一个BroadcastReceiver:

class NotificationHandleReceiver : BroadcastReceiver() {
    companion object {
        const val NOTIFICATION_HANDLE_ACTION = "notification_handle_action"
        const val NOTIFICATION_LINK = "notificationLink"
        const val TAG = "NotificationReceiver"
    }
    override fun onReceive(context: Context, intent: Intent?) {
        if (intent?.action == NOTIFICATION_HANDLE_ACTION) {
            val link = intent.getStringExtra(NOTIFICATION_LINK)
        }
    }
}

别忘了在清单文件中还需要静态注册BroadcastReceiver:

    <receiver
        android:name=".NotificationHandleReceiver"
        android:exported="false">
        <intent-filter>
            <action android:name="notification_handle_action" />
        </intent-filter>
    </receiver>

然后创建一个上面BroadcastReceiver的Intent,在intent.putExtra传入相应的点击通知之后需要识别的操作:

   fun generateDefaultBroadcastPendingIntent(linkParams: (() -> String)?): PendingIntent {
        val intent = Intent(NotificationHandleReceiver.NOTIFICATION_HANDLE_ACTION)
        intent.setPackage(context.packageName)
        linkParams?.let {
            val params = it.invoke()
            intent.putExtra(NotificationHandleReceiver.NOTIFICATION_LINK, params)
        }
        return PendingIntent.getBroadcast(
            context,
            notifyId,
            intent,
            PendingIntent.FLAG_IMMUTABLE
        )
    }

这样生成的PendingIntent再builder.setContentIntent(pendingIntent),在我们点击通知之后,NotificationHandleReceiver的onReceive里就会收到信息了,根据信息处理后续操作即可。

PendingIntent.getActivity

Activity的PendingIntent用于跳转到指定activity,创建一个跳转activity的Intent(同普通的页面跳转的Intent),也是同上面在intent.putExtra传入相应的点击通知之后需要识别的操作:

        val intent = Intent(this, XXXX::class.java).apply {
            putExtra("title", title).putExtra("content", content)
        }
        return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)

也是这样生成的PendingIntent再builder.setContentIntent(pendingIntent),在我们点击通知之后,就会跳转到对应的activity页面,然后intent里就会收到信息了,根据信息处理后续操作即可。

Android12之PendingIntent特性

行为变更:以 Android 12 为目标平台的应用

查看上面关于Android12的特性

在Android12平台上有关于PendingIntent的两点特性:

一是待处理 intent 可变性,必须为应用创建的每个PendingIntent对象指定可变性,这也是上面创建PendingIntent时需要设置flag为PendingIntent.FLAG_IMMUTABLE。

二是通知 trampoline 限制,以 Android 12 或更高版本为目标平台的应用无法从用作通知 trampoline 的服务广播接收器中启动 activity。换言之,当用户点按通知或通知中的操作按钮时,您的应用无法在服务或广播接收器内调用startActivity()。所以当需要点击通知实现activity跳转时,需要使用PendingIntent. getActivity,而不是使用PendingIntent.getBroadcast,然后在BroadcastReceiver里实现activity跳转,后者方式在Android 12 或更高版本为目标平台的应用中将被限制。

配合WorkManager发送延迟通知

配合上WorkManager,就能实现发送延迟通知,主要是通过OneTimeWorkRequest的延迟特性。

创建一个延迟的OneTimeWorkRequest,加入WorkManager队列中:

    fun sendWorkRequest(
        context: Context,
        reminderId: Int,
        title: String,
        content: String,
        link: String,
        triggerTime: Long
    ): OneTimeWorkRequest {
        val duration = triggerTime - System.currentTimeMillis()
        val data =
            Data.Builder().putInt(REMINDER_WORKER_DATA_ID, reminderId).putString(REMINDER_WORKER_DATA_TITLE, title)
                .putString(REMINDER_WORKER_DATA_CONTENT, content).putString(REMINDER_WORKER_DATA_LINK, link)
                .build()
        val uniqueWorkName =
            "reminderData_${reminderId}"
        val request = OneTimeWorkRequest.Builder(ReminderWorker::class.java)
            .setInitialDelay(duration, TimeUnit.MILLISECONDS)
            .setInputData(data)
            .build()
        WorkManager.getInstance(context)
            .enqueueUniqueWork(uniqueWorkName, ExistingWorkPolicy.REPLACE, request)
        return request
    }

然后在doWork方法中拿到数据进行我们上面的通知发送显示即可。具体关于OneTimeWorkRequest的使用在本文中就不详细说明了。当需要发送延迟通知时,知道可以通过配合WorkManager实现。

Android13 通知权限

在目前最新的Android 13(API 级别 33)上对于通知增加了权限限制,具体可看官方描述:

通知运行时权限

到此这篇关于Android Notification通知使用详解的文章就介绍到这了,更多相关Android Notification内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Flutter路由的跳转、动画和传参详解(最简单)

    Flutter路由的跳转、动画和传参详解(最简单)

    这篇文章主要给大家介绍了关于Flutter路由的跳转、动画和传参的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-01-01
  • Android中实现淘宝购物车RecyclerView或LIstView的嵌套选择的逻辑

    Android中实现淘宝购物车RecyclerView或LIstView的嵌套选择的逻辑

    这篇文章主要介绍了Android中实现淘宝购物车RecyclerView或LIstView的嵌套选择的逻辑,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-12-12
  • Android权限如何禁止以及友好提示用户开通必要权限详解

    Android权限如何禁止以及友好提示用户开通必要权限详解

    这篇文章主要给大家介绍了关于Android权限如何禁止以及友好提示用户开通必要权限的相关资料,文中通过示例代码介绍的非常详细,对各位Android开发者们具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • Android显式Intent与隐式Intent的使用详解

    Android显式Intent与隐式Intent的使用详解

    Intent的中文意思是“意图,意向”, Intent对Android的核心和灵魂,是各组件之间的桥梁。四大组件分别为Activity 、Service、BroadcastReceiver、ContentProvider。而这四种组件是独立的,它们之间可以互相调用,协调工作,最终组成一个真正的Android应用
    2022-09-09
  • Android framework ATMS启动流程

    Android framework ATMS启动流程

    这篇文章主要为大家介绍了Android framework ATMS启动流程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • Android开发之对话框案例详解(五种对话框)

    Android开发之对话框案例详解(五种对话框)

    本文通过实例代码给大家分享了5种android对话框,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-09-09
  • 自定义搜索功能Android实现

    自定义搜索功能Android实现

    这篇文章主要为大家详细介绍了自定义搜索功能,由Android代码实现,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • 超过百万的StackOverflow Flutter 20大问题(推荐)

    超过百万的StackOverflow Flutter 20大问题(推荐)

    这篇文章主要介绍了超过百万的StackOverflow Flutter 问题,有的问题在stackoverflow上有几十万的阅读量,说明很多人都遇到了这些问题,把这些问题整理分享给大家需要的朋友可以参考下
    2020-04-04
  • Android自定义View之酷炫数字圆环

    Android自定义View之酷炫数字圆环

    这篇文章主要为大家详细介绍了Android自定义View之酷炫数字圆环,实现效果很酷,,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-01-01
  • 去掉RecycleView或者ListView上下滑动阴影的方法

    去掉RecycleView或者ListView上下滑动阴影的方法

    下面小编就为大家分享一篇去掉RecycleView或者ListView上下滑动阴影的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01

最新评论