"Bad notification for startForeground: Invalid channel for service notification" even though channel has been set

0

What could be the possible other causes of a

Fatal Exception: android.app.RemoteServiceException
Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification

besides not having a channel set? It seems to happen only on Android 8 and 9

My stacktrace shows that channel has a value:

invalid channel for service notification: Notification(channel=com.myapp.notifications pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x52 color=0x00000000 category=service number=0 vis=PRIVATE semFlags=0x0 semPriority=0 semMissedCount=0)

so it seems that the channel has been created correctly.

My background service is set with the usual

    public static final String NOTIFICATION_CHANNEL_ID = "com.myapp.notifications";
    public static final String SERVICE_CHANNEL_ID = "com.myapp.services";
    public static final int NOTIFICATION_ID = 100;

    @Override
    public void onCreate() {
        super.onCreate();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForeground(2, buildNotification(getApplicationContext()));
        }
    }

    @RequiresApi(Build.VERSION_CODES.O)
    Notification buildNotification(Context context) {
        String channelId = SERVICE_CHANNEL_ID;
        setupNotificationChannel(context, channelId);

        return NotificationCompat.Builder(context, channelId)
                .setOngoing(true)
                .setSmallIcon(R.drawable.app_icon)
                .setCategory(Notification.CATEGORY_SERVICE)
                .setAutoCancel(true)
                .setChannelId(channelId)
                .build();
    }

    @RequiresApi(Build.VERSION_CODES.O)
    void setupNotificationChannel(Context context, String channelId) {
        NotificationManager notificationManager = getNotificationManager(context);

        if (notificationManager.getNotificationChannel(channelId) == null) {
            NotificationChannel channel = NotificationChannel(channelId, getChannelName(channelId), getChannelImportance())
            channel.setDescription(getChannelDescription(channelId))
            notificationManager.createNotificationChannel(channel)
        }
    }

I also display some push notifications in a similar way:

    public void showNotification(Context context) {
        NotificationManager notificationManager = getNotificationManager(context);

        String channelId = SHRNotificationService.NOTIFICATION_CHANNEL_ID;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            setupNotificationChannel(context, channelId);
        }

        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId)
                .setSmallIcon(android.R.drawable.stat_sys_download)
                .setContentTitle(getNotificationTitle())
                .setColor(ContextCompat.getColor(context, R.color.BLUE))
                .setChannelId(channelId)
                .setPriority(getNotificationPriority(channelId))
                .setAutoCancel(false)
                .setOngoing(true)
                .setOnlyAlertOnce(true);

        notificationManager.notify(NOTIFICATION_ID, builder.build());
    }

I have the

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

in the Manifest.

What is also unclear is that the stacktrace refers to a notification from the service category, with com.myapp.notifications as the channel Id, but none of the background services or notifications meet both these conditions.

android
android-service
android-notifications
asked on Stack Overflow Jun 4, 2019 by J. Doe • edited Jun 4, 2019 by Ricardo A.

1 Answer

0

It's been a while, but I think this is how it you want to make it look:

     fun sendToForegroundWithNotification() {
        val CHANNEL_ID = "YourChannelId"

        @Suppress("DEPRECATION") //for the NotificationBuilder < API26 ctor
        val notificationBuilder: Notification.Builder
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // O > need a channel, create one
            notificationManager.createNotificationChannel(
                    NotificationChannel(
                            CHANNEL_ID,
                            "Title",
                            NotificationManager.IMPORTANCE_DEFAULT
                    )
            )
            notificationBuilder = Notification.Builder(this, CHANNEL_ID)
        } else notificationBuilder = Notification.Builder(this)


        val notification = notificationBuilder
                .setContentTitle(getText(R.string.app_name))
                .setContentText(getText(R.string.your_content))
                .setSmallIcon(R.drawable.some_icon)
                .etc(whatever you need)
                .build()


        // since you're in your Service, you can call startFg directly:
        startForeground(666, notification) // ;-)

     }

answered on Stack Overflow Jun 4, 2019 by Martin Marconcini

User contributions licensed under CC BY-SA 3.0