5

你真的懂android通知消息吗?

 3 years ago
source link: http://www.androidchina.net/11847.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
你真的懂android通知消息吗? – Android开发中文站
你的位置:Android开发中文站 > 热点资讯 > 你真的懂android通知消息吗?

通知是 android 系统存在至今为止被变更最为频繁的 api 之一,android 4.1、4.4、5.0、7.0、8.0 都对通知做过比较大的改动。到了 8.0 通知功能趋于稳定,至今没有做过更大的改动。

对一个 api 进行如此大的照顾那么这必然是个非常重要的 api 了。那么就跟随我一起揭开通知一点都不神秘的面纱吧。

注:本文主要讲应用

创建简单通知

我们使用 NotificationCompat 来创建通知,使用 NotificationCompat 可以兼容所有的系统版本,不需要我们去手动兼容版本。

创建通知分为两个步骤:

notificationManager.createNotificationChannel(channel)

安卓 8.0 系统要求必须创建渠道才能展示通知,所以我们在 8.0 的系统版本中,必须添加创建渠道的方法。

创建渠道不一定非要在展示通知的时候做,同一个渠道只需要被创建一次即可(多次亦可)。我们可以在我们即将展示通知的时候创建,可以再应用启动的时候创建,也可以在 activity 中创建。总之渠道创建非常灵活

如果渠道已经存在我们仍然调用了创建渠道方法,那么什么也不会做,很安全

下面代码是我们创建渠道的完整代码:

private val channelName = "安安安安卓"
private val channelId = "channelId"
fun createNotificationChannel(context: Context): NotificationChannel? {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val descriptionText = "渠道描述"
            val importance = NotificationManager.IMPORTANCE_DEFAULT
            val channel = NotificationChannel(channelId, channelName, importance).apply {
                description = descriptionText
            }
            val notificationManager: NotificationManager =
                context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
            return channel
        }
        return null
    }
渠道重要性设置

需要注意,渠道的优先级和通知的优先级是不同的,注意区分

val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(channelId, channelName, importance)
复制代码

上面的代码创建了通知的重要程度,我们需要说明一下 NotificationChannel 的第三个参数,也就是渠道的重要程度,这个设置不同的值,用户收到通知后手机的展示包括声音、震动、是否弹出都会不同,下面看一下参数的四种设置(四个参数在不同手机的渠道展示不同):

  • IMPORTANCE_HIGH 收到通知发出提示语,并且会浮动提示用户(小米手机表示紧急)
  • IMPORTANCE_DEFAULT 收到通知发出提示语,不会浮动提示(小米手机表示高)
  • IMPORTANCE_LOW 收到通知不会发出声音,状态栏有小图标展示(小米手机表示中)
  • IMPORTANCE_MIN 根本看不到通知(所以你压根就别用就 ok 了),不过似乎可以用于禁用通知的场景(小米手机表示低)
禁用某个渠道的通知方法

我们使用创建渠道的方式实现禁用通知,如下:

比如我们第一次创建渠道的时候代码如下:

val importance = NotificationManager.IMPORTANCE_HIGH
            val channel = NotificationChannel(channelId, channelName, importance)

这行代码会创建一个有声音提示、横幅展示(google 文档管这个叫偷窥模式 )的渠道。

如果此时用户通过我们 app 内部的设置想不在收到我们这个渠道的通知,我们需要如下代码这样做:

val importance = NotificationManager.IMPORTANCE_MIN
            val channel = NotificationChannel(channelId, channelName, importance)

与上一处的代码的区别是把 IMPORTANCE_HIGH 改成了 IMPORTANCE_MIN,因此我们的渠道就变成了 低级别通知渠道,收到通知也无法展示,因此用户根本看不到通知,从而实现了通知禁用。

还有一点需要注意,我们可以通过代码将一个高优先级的渠道设置为低优先级渠道,但是无法将低优先级渠道设置为高优先级渠道。

通知大家都太熟悉,直接上代码,记得看注释

private val channelName = "安安安安卓"
    private val channelId = "channelId"
    fun showNotification(context: Context) {
        val notification = NotificationCompat.Builder(context, channelName)//这里的渠道名就是你自己想展示通知对应的渠道分组
            .setSmallIcon(R.drawable.apple)//设置状态栏展示的通知样式
            .setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.apple))//设置通知中的图标样式
            .setContentTitle("公众号")//设置通知标题
            .setContentText("安安安安卓")//设置通知正文
            .setChannelId(channelId)//设置通知渠道,这个渠道id必须是和我们创建渠道时候的id对应
            .setPriority(NotificationCompat.PRIORITY_DEFAULT).build()//设置通知优先级
        NotificationManagerCompat.from(context).notify(13, notification)
    }

强调一下:展示通知之前一定要先创建渠道

通知中的优先级

设置方法:NotificationCompat.Builder.setPriority 通知优先级极容易跟渠道优先级混淆,一定要注意区分 通知优先级有以下几种:

  • PRIORITY_DEFAULT = 0;默认优先级
  • PRIORITY_LOW = -1; 低优先级
  • PRIORITY_MIN = -2;最低优先级
  • PRIORITY_HIGH = 1;高优先级
  • PRIORITY_MAX = 2;最高优先级

这个参数主要是给我们的通知进行排序,重要的通知放在前面展示。这可以帮助我们第一时间找到最重要的通知进行处理,这很实用不是吗?

模拟器的展示效果:

创建展开式通知

我们可以再创建 NotificationCompat.Builder 的时候加上如下调用就可以展示展开式通知:

 .setStyle(
                NotificationCompat.BigTextStyle()
                    .bigText("本文由 公众号 \"安安安安卓\"作者原创,禁抄袭\n 北国风光," +
                            "千里冰封,万里雪飘,望长城内外,惟余莽莽,大河上下,顿失滔滔,山舞银蛇,原驰蜡象,欲与天公试比高。" +
                            "须晴日,看银装素裹,分外妖娆")
            )

通知默认是展开式的,长按通知可以在短文本和长文本之间来回切换

设置通知的点击事件

如下代码实现一个可点击的通知栏

  fun showNotification(context: Context) {
        val intent = Intent(context,OnlyShowActivity::class.java).apply {
            flags=Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        }
        val pendingIntent=PendingIntent.getActivity(context,0,intent,0)
        val notification = NotificationCompat.Builder(context, channelId)
            .setContentText("点击通知跳转的一个页面中")
            .setContentTitle("可点击通知")
            .setSmallIcon(R.drawable.apple)
            .setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.apple))
            .setAutoCancel(true)//设置点击了通知,则通知自动消失
            .setContentIntent(pendingIntent)
            .build()
        NotificationManagerCompat.from(context).notify(++count, notification)
    }

给通知栏设置按钮

我们可以通过 addAction 给通知设置 action,同时可以指定一个 PendingIntent。

fun showBtnNotification(context: Context) {
        val intent = Intent(context, OnlyShowActivity::class.java)
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        val pendingIntent = PendingIntent.getActivity(context, 0, intent, 0)
        val notification = NotificationCompat.Builder(context, channelId)
            .setSmallIcon(R.drawable.apple)
            .setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.apple))
            .setContentText("安安安安卓,北国风光,千里冰封,万里雪飘")
            .setContentTitle("按钮通知")
            .addAction(R.drawable.person, "李白", pendingIntent)
            .addAction(R.drawable.apple, "杜甫", pendingIntent)
            .addAction(R.drawable.apple, "王维", pendingIntent)
            .setAutoCancel(true)
            .build()
        NotificationManagerCompat.from(context).notify(++count, notification)
    }

设置进度条

 private val countdown = object : CountDownTimer(15 * 1000, 1000) {
        private val perdegree = 100 / 15
        var count = 0
        override fun onTick(millisUntilFinished: Long) {
            count++
            showNotification(count * perdegree)//更新进度
        }

        override fun onFinish() {
            showNotification(100)
            count = 0
        }
    }

    /**
     * 启动一个可动的进度条
     */
    fun start() {
        countdown.start()
    }

    private fun showNotification(progress: Int) {
        val builder = NotificationCompat.Builder(context, channelId)
            .setSmallIcon(R.drawable.apple)
            .setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.person))
            .setColor(Color.GREEN)
            .setContentTitle("这是个进度标题")

        NotificationManagerCompat.from(context).apply {
            builder.setProgress(100, progress, false)
            builder.setContentText("下载进度 $progress%")
            notify(count, builder.build())
        }
    }

设置自定义通知

我们可以通过 RemoteViews 指定一个布局,通过 setCustomContentView 设置我们的自定义布局 代码:

 fun showNotification(context: Context){
        val remoteViews = RemoteViews(context.packageName, R.layout.item_notification)
        val notification = NotificationCompat.Builder(context, channelId)
            .setContentTitle("这个通知的布局是自定义的")
            .setContentText("安安安安卓")
            .setSmallIcon(R.drawable.apple)
            .setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.person))
            .setCustomContentView(remoteViews)
            .build()
        NotificationManagerCompat.from(context).notify(count,notification)
    }

我们的 xml 代码预览图:

最终效果图:

其它的知识点

  1. 从 android8.1 开始,应用一秒钟最多只能发出一次通知提示音,如果出现多条通知只有一条通知可以出发提示音
  2. 创建通知的几种样式:NotificationCompat.BigPictureStyle、NotificationCompat.BigTextStyle、NotificationCompat.DecoratedCustomViewStyle
  3. NotificationCompat.Builder.setGroup 方法可以创建一组通知
  4. NotificationManager.getNotificationChannel()或 NotificationManager.getNotificationChannels()两个方法可以获取通知的渠道,通过获取到的渠道可以获取此渠道是否开启声音、渠道通知的重要级别。我们可以据此提示用户打开相应的设置,下面代码展示了打开通知渠道的方法:
  Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
    intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
    intent.putExtra(Settings.EXTRA_CHANNEL_ID, myNotificationChannel.getId());
    startActivity(intent);
  1. 删除渠道的方法 deleteNotificationChannel()
  2. 我们可以调用渠道的 NotificationChannel.setShowBadge(false)方法关闭桌面图标圆点。这个其实很有用,比如当你用通知展示下载进度条的时候这条通知明显是不需要展示圆点的,还有大部分的本地提醒类通知都不会希望显示圆点的,用这个方法正好
  3. NotificationCompat.Builder.setNumber 方法可以设置桌面图标的红点数量
  4. 通过 NotificationCompat.DecoratedCustomViewStyle 样式可以给内容区域创建自定义布局。样式就是通知展示图标在左,我们自定义的布局在右,不过这个感觉就没啥用了。
  5. 自定义布局的通知也可以给内部的 view 添加点击跳转事件,实现方法如下代码:
 val remoteViews = RemoteViews(context.packageName, R.layout.item_notification)
        val intent = Intent(context,OnlyShowActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(context,0,intent,0)
        remoteViews.setOnClickPendingIntent(R.id.iv_pendingintent_click,pendingIntent)

Recommend

  • 59

    (点击上方公众号,可快速关注) 来源: 太平洋电脑网 http://ww...

  • 52

    关于 HTML5 ,写了不少文章,总觉得相关的高级 API 都得过一遍。系统的了解,站在更高的高度去思考问题,这样才能事半功倍。 一、先睹为快 我们先来尝试一个最简单的例子,打开 chrome 开发者工具,...

  • 36

    现如今消息通知也是一桩麻烦事,这篇文章旨在介绍几种通知模型,帮助你的APP挑选到合适的通知模型。 通知是指源自于APP以用户为目标的信息片段,以下是通知的几个重要组成部分: 来源(Source):这是APP中生成通知的源头。每个APP根据自己不同的内容体系可以

  • 12

    转自: Doocs开源社区 经常有朋友反馈说 邮箱被 GitHub 的消息通知狂轰滥炸 ,各种无关的邮件提醒搞得很烦。

  • 8
    • www.cnblogs.com 3 years ago
    • Cache

    iOS开发系列--通知与消息机制

    iOS开发系列--通知与消息机制 在多数移动应用中任何时候都只能有一个应用程...

  • 2
    • www.woshipm.com 3 years ago
    • Cache

    消息通知系统设计

    编辑导语:在移动互联网时代,我们每个人每天都可以接收到无数消息通知。那么在用户不断被繁杂琐碎的消息覆盖的情况下,产品如何让消息高效精准地触达用户、并且让用户可以及时便利地反馈平台呢?本文作者就阐述了消息通知系统设计的几大要点,相信...

  • 18

    V2EX  ›  Java 轻量级 Java 应用消息通知中心   Aidenboss · 5 小时 5 分钟前 · 118 次点击

  • 2

    如何详尽的梳理App里的消息通知? 目前在做社交产品,不知如何将消息通知梳理的更清晰一些?求大佬指教?或者有比较优秀的软件推荐学习吗?

  • 2
    • dawner.top 2 years ago
    • Cache

    关于手机通知消息的展示

    关于手机通知消息的展示起源:原生安卓会把推送的消息的应用图标依次展示在状态栏上,图标都为白色,国内定制安卓的做法则各有千秋。(2020.06.17)

  • 4
    • blog.lilydjwg.me 2 years ago
    • Cache

    微信消息通知的困扰

    一直以来,不得不用的微信以其糟糕的通知体验让我十分不爽。 在手机上,我使用的是 Google Play 商店里的微信。在电脑上,我使用的是通过 Wine 运行的 Windows 版本微信([archlin...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK