iT邦幫忙

0

【Android-Notification(通知)】 介紹+實作練習

Tom 2021-06-01 19:16:253952 瀏覽
  • 分享至 

  • xImage
  •  

前言:
通常會和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


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言