Android - Notification Channel API >= 26 is not working properly

10,653

Solution 1

i found this in the documentation. May be it will help you :

On Android 8.0 (API level 26) and above, importance of a notification is determined by the importance of the channel the notification was posted to. Users can change the importance of a notification channel in the system settings (figure 12). On Android 7.1 (API level 25) and below, importance of each notification is determined by the notification's priority.

And also :

Android O introduces notification channels to provide a unified system to help users manage notifications. When you target Android O, you must implement one or more notification channels to display notifications to your users. If you don't target Android O, your apps behave the same as they do on Android 7.0 when running on Android O devices.

And finally :

  • Individual notifications must now be put in a specific channel.
  • Users can now turn off notifications per channel, instead of turning off all notifications from an app.
  • Apps with active notifications display a notification "badge" on top of their app icon on the home/launcher screen.
  • Users can now snooze a notification from the drawer. You can set an automatic timeout for a notification.
  • Some APIs regarding notification behaviors were moved from Notification to NotificationChannel. For example, use NotificationChannel.setImportance() instead of NotificationCompat.Builder.setPriority() for Android 8.0 and higher.

Solution 2

Thank you all guys,

I managed to solve it by simply creating a NotificationCompat.Builder and NotificationChannel for each and every case, and notify each Builder when its condition is met.

I don't know if this is the best practice, but I'll try to optimize the code later, if anyone has an opinion on that feel free. But it worked so fine now.

Here's my code:

NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationCompat.Builder builder_all, builder_sound, builder_vibrate, builder_none;
        NotificationChannel channel_all = new NotificationChannel(CHANNEL_ID_ALL, CHANNEL_NAME_ALL, NotificationManager.IMPORTANCE_HIGH);
        channel_all.enableVibration(true);
        notificationManager.createNotificationChannel(channel_all);

        NotificationChannel channel_sound = new NotificationChannel(CHANNEL_ID_SOUND, CHANNEL_NAME_SOUND, NotificationManager.IMPORTANCE_HIGH);
        channel_sound.enableVibration(false);
        notificationManager.createNotificationChannel(channel_sound);

        NotificationChannel channel_vibrate = new NotificationChannel(CHANNEL_ID_VIBRATE, CHANNEL_NAME_VIBRATE, NotificationManager.IMPORTANCE_HIGH);
        channel_vibrate.setSound(null, null);
        channel_vibrate.enableVibration(true);
        notificationManager.createNotificationChannel(channel_vibrate);

        NotificationChannel channel_none = new NotificationChannel(CHANNEL_ID_NONE, CHANNEL_NAME_NONE, NotificationManager.IMPORTANCE_HIGH);
        channel_none.setSound(null, null);
        channel_none.enableVibration(false);
        notificationManager.createNotificationChannel(channel_none);

        //Boolean for Sound or Vibrate are chosen
        if(sound && vibrate) {
            builder_all = new NotificationCompat.Builder(context, CHANNEL_ID_ALL);
            builder_all.setSmallIcon(R.drawable.ic_logo)
                    .setContentTitle(title)
                    .setContentText(text)
                    .setAutoCancel(true)
                    .setOnlyAlertOnce(false);
            switch (transition) {
                case Geofence.GEOFENCE_TRANSITION_ENTER:
                    builder_all.setSmallIcon(R.drawable.ic_entered_white);
                    break;
                case Geofence.GEOFENCE_TRANSITION_EXIT:
                    builder_all.setSmallIcon(R.drawable.ic_left_white);
                    break;
            }

            notificationManager.notify(notificationID, builder_all.build());
        } else if(sound && !vibrate) {
            builder_sound = new NotificationCompat.Builder(context, CHANNEL_ID_SOUND);
            builder_sound.setSmallIcon(R.drawable.ic_logo)
                    .setContentTitle(title)
                    .setContentText(text)
                    .setAutoCancel(true)
                    .setOnlyAlertOnce(false);
            switch (transition) {
                case Geofence.GEOFENCE_TRANSITION_ENTER:
                    builder_sound.setSmallIcon(R.drawable.ic_entered_white);
                    break;
                case Geofence.GEOFENCE_TRANSITION_EXIT:
                    builder_sound.setSmallIcon(R.drawable.ic_left_white);
                    break;
            }

            notificationManager.notify(notificationID, builder_sound.build());
        } else if(!sound && vibrate) {
            builder_vibrate = new NotificationCompat.Builder(context, CHANNEL_ID_VIBRATE);
            builder_vibrate.setSmallIcon(R.drawable.ic_logo)
                    .setContentTitle(title)
                    .setContentText(text)
                    .setAutoCancel(true)
                    .setOnlyAlertOnce(false);
            switch (transition) {
                case Geofence.GEOFENCE_TRANSITION_ENTER:
                    builder_vibrate.setSmallIcon(R.drawable.ic_entered_white);
                    break;
                case Geofence.GEOFENCE_TRANSITION_EXIT:
                    builder_vibrate.setSmallIcon(R.drawable.ic_left_white);
                    break;
            }

            notificationManager.notify(notificationID, builder_vibrate.build());
        } else if(!sound && !vibrate) {
            builder_none = new NotificationCompat.Builder(context, CHANNEL_ID_NONE);
            builder_none.setSmallIcon(R.drawable.ic_logo)
                    .setContentTitle(title)
                    .setContentText(text)
                    .setAutoCancel(true)
                    .setOnlyAlertOnce(false);
            switch (transition) {
                case Geofence.GEOFENCE_TRANSITION_ENTER:
                    builder_none.setSmallIcon(R.drawable.ic_entered_white);
                    break;
                case Geofence.GEOFENCE_TRANSITION_EXIT:
                    builder_none.setSmallIcon(R.drawable.ic_left_white);
                    break;
            }

            notificationManager.notify(notificationID, builder_none.build());
        }
    } else {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(context);

        if(sound && vibrate) {
            //Sound and Vibrate
            builder.setDefaults(Notification.DEFAULT_ALL);
        } else if(sound && !vibrate) {
            //Sound
            builder.setDefaults(Notification.DEFAULT_SOUND);
        } else if(!sound && vibrate) {
            //Vibrate
            builder.setDefaults(Notification.DEFAULT_VIBRATE);
        } else if(!sound && !vibrate) {
            //None
            //Do nothing! just notification with no sound or vibration
        }

        builder.setSmallIcon(R.drawable.ic_logo)
                .setContentTitle(title)
                .setContentText(text)
                .setAutoCancel(true)
                .setOnlyAlertOnce(false)
                .setPriority(Notification.PRIORITY_MAX);

        switch (transition) {
            case Geofence.GEOFENCE_TRANSITION_ENTER:
                builder.setSmallIcon(R.drawable.ic_entered_white);
                break;
            case Geofence.GEOFENCE_TRANSITION_EXIT:
                builder.setSmallIcon(R.drawable.ic_left_white);
                break;
        }

        notificationManager.notify(notificationID, builder.build());
    }
Share:
10,653
Ahmed
Author by

Ahmed

Beginner Android Developer

Updated on June 18, 2022

Comments

  • Ahmed
    Ahmed about 2 years

    I've been struggling with the new NotificationChannels which is introduced in API 26 and up.

    I'm developing an app with an option to choose whether to be notified in four cases:

    1. Sound and Vibrate.
    2. Sound only.
    3. Vibrate only.
    4. No sound or vibrate, just a pop-up.

    In all cases, my app notify with sound and vibrate whatever I choose.

    My code is:

    NotificationCompat.Builder builder;
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder = new NotificationCompat.Builder(context, CHANNEL_ID);
            int importance;
            NotificationChannel channel;
    
            //Boolean for choosing Sound
            if(sound) {
                importance = NotificationManager.IMPORTANCE_DEFAULT;
            } else {
                importance = NotificationManager.IMPORTANCE_LOW;
            }
    
            channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, importance);
            channel.setDescription(CHANNEL_DESC);
    
            //Boolean for choosing Vibrate
            if(vibrate) {
                channel.enableVibration(true);
            } else {
                channel.enableVibration(false);
            }
    
            notificationManager.createNotificationChannel(channel);
        } else {
            builder = new NotificationCompat.Builder(context);
        }
    
        if(sound && vibrate) {
            //Sound and Vibrate
            builder.setDefaults(Notification.DEFAULT_ALL);
        } else if(sound && !vibrate) {
            //Sound
            builder.setDefaults(Notification.DEFAULT_SOUND);
        } else if(!sound && vibrate) {
            //Vibrate
            builder.setDefaults(Notification.DEFAULT_VIBRATE);
        } else if(!sound && !vibrate) {
            //None
            //Do nothing! just notification with no sound or vibration
        }
    
        builder.setSmallIcon(R.drawable.ic_logo)
                .setContentTitle(title)
                .setContentText(text)
                .setAutoCancel(true)
                .setOnlyAlertOnce(false)
                .setPriority(Notification.PRIORITY_MAX);
    

    Also, I change CHANNEL_ID every time I run the app, so it gets a fresh Channel ID every time just for testing until I find a solution.

    Of course, it works fine with API less than 26.

    Thank you, guys!

  • Ahmed
    Ahmed over 6 years
    Thank you @Arnauld, I'll try to figure out something specially with the last one (Individual notifications must now be put in a specific channel), if it means that every notification type must have its own channel id.
  • Arnauld Alex
    Arnauld Alex over 6 years
    github.com/googlesamples/android-NotificationChannels May be try with this repo of google. Good luck
  • Mohammedsalim Shivani
    Mohammedsalim Shivani over 6 years
    If this solution worked for you, then it should be the accepted answer.
  • Mohammedsalim Shivani
    Mohammedsalim Shivani over 6 years
    It's not my question. So I can't do it. Only the OP can accept it.
  • Ali Asadi
    Ali Asadi over 5 years
    related point to take care off not to make an incorrect implementation by using both enableVibration() and setVibrationPattern() take look here: proandroiddev.com/…