Android Oreo上的NotificationManagerCompat

19

在使用NotificationManagerCompatNotificationCompat时,有没有一种方法可以在Android Oreo上设置通道?

3个回答

20

由于NotificationManagerCompat只是一个使生活更加轻松的包装类,因此您可以正常创建通道:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    val name = getString(R.string.channel_title)
    val description = getString(R.string.channel_description)
    val importance = NotificationManager.IMPORTANCE_HIGH
    val mChannel = NotificationChannel(CHANNEL_ID, name, importance)
    mChannel.description = description
    mChannel.enableLights(true)
    mChannel.lightColor = Color.parseColor("#5B3C88")
    mChannel.enableVibration(true)
    mChannel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
    val manager = (context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager)
    manager.createNotificationChannel(mChannel)
}

在发布通知时,请使用NotificationManagerCompat,但不要忘记使用新构造函数构建通知:

NotificationCompat.Builder(context, CHANNEL_ID)

1
仅使用普通的NotificationManager显示通知有何区别? - Florian Walther
@Florian Walther 它使得通知与旧版本兼容。例如,通道 ID 被忽略了。我们每次要创建通知并传递 channelid 或者不传之前都去检查 < API 26 实在是太蠢了。 - DennisVA
1
现在使用 androidx.appcompat:appcompat:1.1.0-rc01,您可以在 API 26+ 上使用 NotificationManagerCompat.createNotificationChannel() - Onkar Nene
非常整洁。你知道吗,顺便问一下,如何使这个通知也出现在Android Auto上? - Josh

16

使用NotificationManagerCompat与AndroidX是推荐的方式。

NotificationManagerCompat 现在支持通知渠道。新版本为NotificationManagerCompat添加了通知渠道方法,因此开发人员可以仅使用NotificationManagerCompat处理通知。

对于Java,请在build.gradle文件中包含以下内容:

implementation'androidx.core:core:1.2.0'

对于Kotlin,请在build.gradle文件中包含以下依赖项,而不是上面的依赖项:

implementation 'androidx.core:core-ktx:1.2.0'

要显示通知,您需要执行以下操作

  1. 创建并注册通知渠道。
  2. 创建通知。
  3. 显示通知

下面的代码片段使用Kotlin编写,但如果需要也可以使用Java。

1. 创建并注册通知渠道。

通知渠道为类似类型的通知提供了共同的视觉和听觉体验。自API 26以来,您现在必须为通知设置一个通道,否则它们将无法在较新的Android版本上显示。

因此,如下所示定义一个帮助程序方法来为您创建通知渠道。

//define your channel id
val CHANNEL_ID = "com.yourpackagename.your_channel_id"

//create notification channel for android Oreo and above devices.
if (Build.VERSION.SDK_INT >= 26) {
    val channel = NotificationChannel(CHANNEL_ID , "Your channel name", NotificationManager.IMPORTANCE_DEFAULT)
    NotificationManagerCompat.from(this).createNotificationChannel(channel)
}

2.创建通知。

使用NotificationCompat.Builder创建一个Notificaiton。请注意CHANNEL_ID被传递给了生成器。

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
    .setSmallIcon(R.drawable.notification_icon)
    .setContentTitle("My notification")
    .setContentText("Much longer text that cannot fit one line...")
    .setStyle(NotificationCompat.BigTextStyle()
            .bigText("Much longer text that cannot fit one line..."))
    .setPriority(NotificationCompat.PRIORITY_DEFAULT)

3. 显示通知

要显示通知,调用NotificationManagerCompat.notify(),将其传递一个唯一的通知ID和NotificationCompat.Builder.build() 的结果。

   NotificationManagerCompat.from(this).notify(notificationId, builder.build())

就这些 :)


鉴于AndroidCompat被androidx替换是未来的趋势和推荐做法,Darish给出了最现代的答案;我希望razvan-cristian-lung @praful-bhatnagar仍然可以更新他们的答案以反映/指向这种迁移? - anthropic android
这个答案让我省了很多麻烦。谢谢Darish! - Silas
1
也许我漏掉了什么,但是那个方法需要一个 android.app.NotificationChannel 的列表,而这个只存在于 API 26 上,所以如何在不检查 API 26 的情况下创建通道并传递它呢...? - androidguy
@androidguy 在创建 NotificationChannel 时,您仍需要检查 API 26。一旦通道对象准备就绪,您可以使用 NotificationManagerCompat 将其注册到系统中。 - Darish

6

我通常使用这个类来管理通知渠道:

class NotificationManager(private val context: Context) {

    companion object {
        private val CHANNEL_ID = "YOUR_CHANNEL_ID"
        private val CHANNEL_NAME = "Your human readable notification channel name"
        private val CHANNEL_DESCRIPTION = "description"
    }

    @RequiresApi(Build.VERSION_CODES.O)
    fun getMainNotificationId(): String {
        return CHANNEL_ID
    }

    @RequiresApi(Build.VERSION_CODES.O)
    fun createMainNotificationChannel() {
            val id = CHANNEL_ID
            val name = CHANNEL_NAME
            val description = CHANNEL_DESCRIPTION
            val importance = android.app.NotificationManager.IMPORTANCE_LOW
            val mChannel = NotificationChannel(id, name, importance)
            mChannel.description = description
            mChannel.enableLights(true)
            mChannel.lightColor = Color.RED
            mChannel.enableVibration(true)
            val mNotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as android.app.NotificationManager
            mNotificationManager.createNotificationChannel(mChannel)
    }
}

然后您可以像这样使用工具:
fun createNotificationCompatBuilder(context: Context): NotificationCompat.Builder {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        return NotificationCompat.Builder(context, NotificationManager(context).mainNotificationId)
    } else {
        return NotificationCompat.Builder(context)
    }
}

通过这种方式,您可以在应用程序的任何位置使用与之前相同的签名,并且在将来更改时可以轻松更改它。


非常整洁。你知道怎么让这个通知也出现在Android Auto上吗? - Josh
@Josh 抱歉,还没有机会在 Android Auto 上测试通知,所以这里无法给出建议。 - A. Shevchuk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接