[安卓开发/kotlin]基础 显示通知内容

发布于 2021-08-18  610 次阅读


本文同步发布于b站专栏,为本人所发.

我在半个月前开始上手kotlin的安卓开发,现在整合一下我的学习显示通知(Notification)的方法,供各位后来人参考.

以下文章包括:

  • 通知频道
  • 查询是否有通知的权限并获取
  • 进行通知
  • 简单实例

注:该教程可能只兼容安卓8以上的系统

参考网站:创建通知  |  Android 开发者  |  Android Developers (google.cn)

通知频道

在安卓8以上需要创建一个频道才能发送通知,创建一个频道的函数的代码如下所示.注意需要定义一个频道id变量,类型为字符串,在下方所有代码中该变量称作"CHANNAL_ID"

private fun createNotificationChannel()
{
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = "APP测试频道"
val descriptionText = "用于测试APP通知功能"
val importance = NotificationManager.IMPORTANCE_MAX
val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
description = descriptionText
}
// Register the channel with the system
val notificationManager: NotificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}

创建这个函数后,需要在onCreate函数中调用这个函数以创建.

一般来说,创建成功在设置中的该app的通知管理可以看到这个频道,如下图

查询通知的权限以及获得其授权

刚安装app时有一定可能没有悬浮通知权限\频道通知权限甚至APP通知权限被关闭,这时候我们在通知前可能需要检查下是否有对应权限.整个鉴权思路是从app鉴权-频道鉴权-悬浮通知鉴权逐步进行,都开启了就可以通知了.建议在发送通知代码前进行验证.

APP通知

可以通过NotificationManagerCompat的areNotificationsEnabled查看是否有权,值为布尔值.布尔值若为假,就需要使用toast通知用户并通过Intent跳转到设置引导其开启.代码如下:

val notification = NotificationManagerCompat.from(this)
            val isEnabled = notification.areNotificationsEnabled()
            if (isEnabled.toString() == "false") {
                Toast.makeText(this, "APP没有通知权限,请设置", Toast.LENGTH_SHORT).show()
                val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
                intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
                intent.putExtra(Settings.EXTRA_CHANNEL_ID, "1")
                startActivity(intent)
            }

频道通知

当获取频道的Importance时,返回的值为0,即可得知该频道没有通知权限.同样需要通过Intent跳转到设置使用户开启,代码如下:

            if (channel.getImportance().toString() == "0"){
                Toast.makeText(this, "该频道被戴上了口塞,请取下(doge).", Toast.LENGTH_SHORT).show()
                val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
                intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
                intent.putExtra(Settings.EXTRA_CHANNEL_ID, "1")
                startActivity(intent)
            }

悬浮通知

没有了悬浮通知权限,通知的作用就少了一半,也就是说它的重要性低了. 当获取频道的Importance时,返回的值为3,则代表不能发布悬浮通知,同样需要用户开启.代码如下:

            if (channel.getImportance() <= NotificationManager.IMPORTANCE_DEFAULT) {//未开启
                Toast.makeText(this, "请设置悬浮通知权限.", Toast.LENGTH_SHORT).show()
                val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
                intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
                intent.putExtra(Settings.EXTRA_CHANNEL_ID, "1")
                startActivity(intent)
            }

进行通知

你需要使用NotificationCompat.Builder(this, CHANNEL_ID)来设置通知内容,详细的创建内容在谷歌开发者网站有.一般的,我们可能需要这些基本内容

            val builder = NotificationCompat.Builder(this, CHANNEL_ID)
                .setSmallIcon(R.drawable.notification_icon)
                .setContentTitle(showtitle)
                .setContentText(showcontent)
                // 通知优先级,可以设置为int型,范围-2至2
                .setPriority(NotificationCompat.PRIORITY_MAX)
                .setCategory(NotificationCompat.CATEGORY_MESSAGE)
                .setContentIntent(pendingIntent)
                .setAutoCancel(true)
                .setVisibility(VISIBILITY_PUBLIC)

那么我们调用notificationManagerCompat.notify()就可以显示通知了,与此同时需要传入的是CHANNAL_ID以及上方代码创建的bulider变量

with(NotificationManagerCompat.from(this)) {
notify(1, builder.build())
}

简单实例

该实例的界面是两个文本输入框,一个标题一个内容以及一个能够触发事件的按钮.

activity的xml代码如图

内容
标题
按钮

代码块如下(关键部分)

    private fun createNotificationChannel()
    {
            // Create the NotificationChannel, but only on API 26+ because
            // the NotificationChannel class is new and not in the support library
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val name = "APP测试频道"
                val descriptionText = "用于测试APP通知功能"
                val importance = NotificationManager.IMPORTANCE_MAX
                val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
                    description = descriptionText
                }
                // Register the channel with the system
                val notificationManager: NotificationManager =
                    getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                notificationManager.createNotificationChannel(channel)
            }
        }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        createNotificationChannel()
        setContentView(R.layout.activity_main)

    }    
fun showNotification(showtitle: String, showcontent: String) {
        val version = Build.VERSION.SDK_INT
        // Create an explicit intent for an Activity in your app
        val intent = Intent(this, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        }
        val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, 0)

        val mNotificationManager = this.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//Android 8.0及以上

            val channel = mNotificationManager.getNotificationChannel(CHANNEL_ID);//CHANNEL_ID是自己定义的渠道ID
            val notification = NotificationManagerCompat.from(this)
            val isEnabled = notification.areNotificationsEnabled()
            if (isEnabled.toString() == "false") {
                Toast.makeText(this, "APP没有通知权限,请设置", Toast.LENGTH_SHORT).show()
                val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
                intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
                intent.putExtra(Settings.EXTRA_CHANNEL_ID, "1")
                startActivity(intent)
            }
            else if (channel.getImportance().toString() == "0"){
                Toast.makeText(this, "该频道被戴上了口塞,请取下(doge).", Toast.LENGTH_SHORT).show()
                val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
                intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
                intent.putExtra(Settings.EXTRA_CHANNEL_ID, "1")
                startActivity(intent)
            }
            else if (channel.getImportance() <= NotificationManager.IMPORTANCE_DEFAULT) {//未开启
                Toast.makeText(this, "请设置悬浮通知权限.", Toast.LENGTH_SHORT).show()
                val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
                intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
                intent.putExtra(Settings.EXTRA_CHANNEL_ID, "1")
                startActivity(intent)
            }
            // CHANNEL_ID:通道ID,可在类 MainActivity 外自定义。如:val CHANNEL_ID = 'msg_1'
            val builder = NotificationCompat.Builder(this, CHANNEL_ID)
                .setSmallIcon(R.drawable.notification_icon)
                .setContentTitle(showtitle)
                .setContentText(showcontent)
                // 通知优先级,可以设置为int型,范围-2至2
                .setPriority(NotificationCompat.PRIORITY_MAX)
                .setCategory(NotificationCompat.CATEGORY_MESSAGE)
                .setContentIntent(pendingIntent)
                .setAutoCancel(true)
                .setVisibility(VISIBILITY_PUBLIC)
            // 显示通知
            with(NotificationManagerCompat.from(this)) {
                notify(1, builder.build())
            }
//            val notification = builder.build()
//            val oldNotificationManager = getSystemService(Context.NOTIFICATION_SERVICE)
//            NotificationManagerCompat.from(this)
        }
    }
fun connect(view: View) {
    val title = findViewById<EditText>(R.id.editTitle)
    val method = findViewById<EditText>(R.id.editMethod)
    showNotification(title.text.toString(), method.text.toString())
}

效果如图

这是我第一次写有关安卓开发的文章,难免有很多不恰当之处,麻烦各位指出,谢谢!如果作为新手开发遇到任何问题也可以问我,我将会尝试解答!

届ける言葉を今は育ててる
最后更新于 2021-08-18