【Android-Notification(通知)】 介绍+实作练习

前言:
通常会和Broadcast(广播)一起使用,在app status条显示的资料,
可以在App非前台时跳出通知!
因为对於Android还不是很熟悉,如果有任何错误烦请告知,谢谢!

先展示成品

https://ithelp.ithome.com.tw/upload/images/20210601/20138017SHu5on0aEn.png

好的,我们直接来看code

一、 首先创建一个 NotificationUtils.kt 并创建一个扩展函示的funtion
fun NotificationManager.sendNotification(messageBody: String, context:Context){
}

我们可以注意到 NotificationManager,这个类是以下方法会需要用到的

  • NotificationManager.sendNotification:寄通知
  • NotificationManager.createNotificationChannel :创立channel
  • notificationManager.cancelNotification:删掉通知

既然都说到用法了,那就一起提实例化Manager的方法啦!

以下的例子就是以创立channel为目标,实例化的manager

val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(notificationChannel)

二、回到刚刚的 NotificationUtils.kt ,并在 sendNotification的funtion里面新增 builder

val builder = NotificationCompat.Builder(context,"test")
.setSmallIcon(R.drawable.cat1)
.setLargeIcon(bigPicture)
.setContentTitle("未来日本App")
.setContentText(messageBody)
.setColor(ContextCompat.getColor(context,R.color.black))
.setAutoCancel(true)
  • setSmallIcon:设立小的icon,也就是下图左上方的黑色图(颜色好像都会自动改成黑色的?)
  • setLargeIcon:这边需要丢 bitmap的格式(点阵图)
  • setContentTitle:显示在左上方的Title
  • setContentText:显示在左下方(通常由叫sendNotification时当作参数传进去)
  • setColor:这边是指字的颜色,拿的方法要注意一下
  • setAutoCancel:点击时,是否自动删掉通知

位置参考如下图,再把最前头的图片拿回来

https://ithelp.ithome.com.tw/upload/images/20210601/201380175iYBgt3V6n.png

补上点阵图方法

val bigPicture = BitmapFactory.decodeResource(
context.resources,
        R.drawable.big
)

最後补上 notify就完成啦

//发送通知,第一个是 Notification的 ID,此ID,若Status栏位已经有同样的id,则为update
//第二个则是Notification,用 builder.build()去建立它
notify(NOTIFICATION_ID,builder.build())

三、接下来我们要准备创立channel啦

你可能会觉得奇怪,刚刚不是在builder已经有创立了吗?
Android在 Android 8.0,除了原本的

  1. 建立 NotificationManager 物件
  2. 建立 Builder ,并将细节的属性设置添加给上去
  3. 呼叫 Builder.build() 得到 Notification 物件
  4. NotificationManager 执行 notify 方法执行通知

Android 8.0之後现在还要再加上透过createNotificationChannel(),指派channel给NotificationManager

那我们来到ManinActivity.kt,新增以下的code

private fun createChannel(channelId: String,channelName: String){
if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.O){

val notificationChannel = NotificationChannel(channelId,channelName,NotificationManager.IMPORTANCE_LOW)
notificationChannel.apply{
enableLights(true)
            lightColor= Color.RED
enableVibration(true)
            description= "疫情期间请尽量避免外出"
}
//把manager叫出来後,创立 channel
        val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(notificationChannel)
    }
}

接下来细细看~

val notificationChannel = NotificationChannel(channelId,channelName,NotificationManager.IMPORTANCE_LOW)

第一个参数是填写 channel_ID,并须与刚刚的 builder的 id相同

第二个参数则是填写 channel_Name,会在user点选app通知时看到

第三个则是通知的重要性(参考以下级别)

https://ithelp.ithome.com.tw/upload/images/20210601/20138017MLVX4sv5xE.jpg
(图片参考Android官方文件)

再来看设定是否可以闪光+震动以及描述

notificationChannel.apply{
enableLights(true)
    lightColor= Color.RED
enableVibration(true)
    description= "疫情期间请尽量避免外出"
}

最後再把Manager透过刚刚的方式叫出来後,在createNotificationChannel,才算是成功创立channel

val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(notificationChannel)

接下来在override fun onCreate 叫出 funtion并给予 id+name就好!

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

createChannel("test","channelName")

}

四、既然channel都创好了,那就可以寄出 Notification啦,我们回到之前创立好的receiver.kt(这边就不多加叙述了)

并加入sendNotification的 funtion,要记得 也是要透过 NotificationManager叫出来喔

val notificationManager = ContextCompat.getSystemService(context,NotificationManager::class.java)as NotificationManager

notificationManager.sendNotification("哈罗这边是由receiver出来的讯息喔",context)

到目前为止,就已经算成功给予了通知,当跑到receiver时候,就会跑到sendNotification的funtion

五、接下来我们要来新增当点击通知时,打开特定 activity,没错! 就是你心中想的Intent
我们回到NotificationUtils.kt的 NotificationManager.sendNotification 中
新增以下

fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {

val contentIntent = Intent(applicationContext, MainActivity::class.java)

}

但是因为看通知时,你app可能已经关了,所以我们会要用到PendingIntent

  • 我们可以把Intent当作意图,我们想要做的事情,在Activity中我们可以直接执行它,PendingIntent相当於对Intent进行包装,我们不一定要马上执行它,可以把它传递给其他Acitivity/Application执行
  • PendingIntent是由Android系统持有的,也代表当今天创建该PendingIntet的对象被杀死後,这个PendingIntent也是可用的

参考资料:https://blog.csdn.net/yangwen123/article/details/8019739

再来创建PendingIntent

val pendingIntent = PendingIntent.getActivity(context, NOTIFICATION_ID,Intent,PendingIntent.FLAG_UPDATE_CURRENT)

第一个参数:NOTIFICATION_ID,是一开始建立的全域变数,为INT值
第二个参数:刚刚创立的Intent
第三个参数为:PendingIntent
第四个参数为:FLAG_UPDATE_CURRENT 若系统有PendingIntent对象,则保留对象,但是会使用新的Intent来更新之前的PendingIntent数据,详细可以参考上面的参考资料

private val NOTIFICATION_ID = 0

最後在一早建立好的 builder里面新增Intent即完成!!

val builder = NotificationCompat.Builder(context,"test")
        .setContentIntent(pendingIntent)

成品来啦!
图片

最後附上github:https://github.com/i-hung-tseng/Broadcast

参考文章:
https://developer.android.com/codelabs/advanced-android-kotlin-training-notifications#4
https://ithelp.ithome.com.tw/articles/10206930
https://blog.csdn.net/yangwen123/article/details/8019739


<<:  如何在 MAC 上检查 MD5 HASH

>>:  Day 7 (CSS)

让微软帮你管理人员 - Azure Activate Directory

说明 有时候网站需要建立会员资料库,并设定登入验证、授权等等,若这些事情交给Azure服务,或许在某...

.NET Core第29天_Model验证配置准备流程_各种验证资料注解使用方式

新建一个.net core mvc专案後 预设每一个检视之所以都能套用版面配置页 主要是在於藉由.\...

C# 入门之循环

在 C# 中,支持三类循环: do...while 循环 while 循环 for/foreach ...

Day-1 旅程开始

对於Python 只知道一点语法,藉由参加读书会与上网找资料来重自己对於Python了解与实作。 主...

Outlook 开启後,工作管理员内的记忆体使用率一直增加

Outlook开启後,工作管理员内的记忆体使用率一直增加,不论是断网路,或是还原系统,重灌Outlo...