android - 升级到 Android 8.1 后 startForeground 失败

标签 android service kotlin android-notifications background-service

将我的手机升级到 8.1 Developer Preview 后,我的后台服务无法正常启动。

在我长期运行的服务中,我实现了一个 startForeground 方法来启动在创建时调用的持续通知。

@TargetApi(Build.VERSION_CODES.O)
private fun startForeground() {
    // Safe call, handled by compat lib.
    val notificationBuilder = NotificationCompat.Builder(this, DEFAULT_CHANNEL_ID)

    val notification = notificationBuilder.setOngoing(true)
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .build()
    startForeground(101, notification)
}

错误信息:

11-28 11:47:53.349 24704-24704/$PACKAGE_NAMEE/AndroidRuntime: FATAL EXCEPTION: main
    Process: $PACKAGE_NAME, PID: 24704
    android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=My channel pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x42 color=0x00000000 vis=PRIVATE)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1768)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

invalid channel for service notification,显然我的旧 channel DEFAULT_CHANNEL_ID 不再适合我假设的 API 27。什么是合适的 channel ?我试图查看文档

最佳答案

在对不同的解决方案进行了一段时间的修改后,我发现必须在 Android 8.1 及更高版本中创建通知 channel 。

private fun startForeground() {
    val channelId =
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                createNotificationChannel("my_service", "My Background Service")
            } else {
                // If earlier version channel ID is not used
                // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
                ""
            }

    val notificationBuilder = NotificationCompat.Builder(this, channelId )
    val notification = notificationBuilder.setOngoing(true)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setPriority(PRIORITY_MIN)
            .setCategory(Notification.CATEGORY_SERVICE)
            .build()
    startForeground(101, notification)
}

@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel(channelId: String, channelName: String): String{
    val chan = NotificationChannel(channelId,
            channelName, NotificationManager.IMPORTANCE_NONE)
    chan.lightColor = Color.BLUE
    chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
    val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    service.createNotificationChannel(chan)
    return channelId
}

据我了解,后台服务现在显示为普通通知,然后用户可以通过取消选择通知 channel 来选择不显示。

更新: 另外别忘了根据需要添加Android P的前台权限:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

关于android - 升级到 Android 8.1 后 startForeground 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47531742/

相关文章:

android - 将 android 字符串资源值替换为带有 resValue() 或类似内容的 Gradle 任务

android - 刷新 SurfaceView-->OnClickListener Android 上的 Canvas

android - 防止 Activity 在后台做某事

.net - ASP.Net Web 服务响应时间慢

spring - Kotlin 和 Spring MVC - HTTP 状态 400 - 空

android - Eclipse ADT 无法在 SDK 源上设置条件断点 : missing java Project context

javascript - 我可以/应该在 cordova 应用程序中下载 html5 代码吗?

android - EditText() 的奇怪问题 - Android Kotlin

grails - Grails 3.3-如何替换已弃用的服务伪像?

java - 安卓房间 : How to use embedded with a custom query