Android Oreo Notification Channels

JonDouglasJonDouglas USXamarin Team, University, Developer Group Leader Xamurai
edited November 2017 in Xamarin Blog

Have you tried using Android Oreo's Notification Channels yet?

If you haven't, read our blog for a quick primer on Notification Channels and let us know what you think!

Feel free to discuss this post below.

Tagged:

Posts

  • EricBrunnerEricBrunner USMember ✭✭
    Hi

    I miss the following

    1. I have a XF Droid/iOS solution which supports min. SDK API LEVEL 16 in Droid. Now when I upgrade to API-LEVEL 26/27 OREO I am forced to use Notification Channels. But what about my backward compatibility on devices that don't have OREO installed (Android OS < API-LEVEL 26)

    thanks
    Eric
  • JonDouglasJonDouglas USXamarin Team, University, Developer Group Leader Xamurai

    @EricBrunner

    Only Oreo and newer versions of Android require that Notifications have proper channels defined. There are two scenarios that come in mind:

    1. Your app does not target Android 8.0 (API 26) but is ran against a device running Android 8.0 (API 26)

    This situation it will behave as if it were on <= Android 7.1 (API 25)

    1. Your app does target Android 8.0 (API 26) but is ran against a device running < Android 8.0 (API 26)

    This situation will be completely ignored as if it didn't exist. No need to worry about the current implementation breaking.

    So in both situations, your apps that are not running Android 8.0 or greater, these APIs will not be leveraged and it should remain compatible if you do or do not have Notification Channel implementations.

  • EricBrunnerEricBrunner USMember ✭✭

    @JonDouglas
    Hi Jon,
    Thanks for getting back. I am still confused.

    That is my current code I use to create notification on my Droid XF app targeting API-LEVEL 25 (Android 7.1).

    private void CreateNotification(Context context, string desc)
    {
    var notificationManager = GetSystemService(NotificationService) as NotificationManager;
    var uiIntent = new Intent(context, typeof(MainActivity));

            //activity will not be launched if it is already running at the top of the history stack.
            uiIntent.AddFlags(ActivityFlags.SingleTop);
    
            NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
    
            var notification = builder
                .SetContentIntent(PendingIntent.GetActivity(context, 0, uiIntent, 0))
                .SetSmallIcon(Android.Resource.Drawable.SymDefAppIcon)
                .SetTicker("TruckerApp")
                .SetContentTitle("TruckerApp")
                .SetContentText(desc)
                .SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification))
                .SetAutoCancel(true)
                .Build();
    
            notificationManager?.Notify(1, notification);
        }
    

    I would like to target >= API-LEVEL 26 (Android 8) . Now I found that SO answer. Could you provide the change I would have to do in my code to get notifications properly on Android OS below API-LEVEL 26 and above ?

    SO answer

  • JonDouglasJonDouglas USXamarin Team, University, Developer Group Leader Xamurai

    @EricBrunner

    There is no change you need to make for APIs < Oreo. However you need to set a channel in order for APIs >= Oreo to work. Thus if you wanted to, you can follow a similar idea here:

    https://stackoverflow.com/a/44534559/1048571

    Google also recommends this:

    Apps targeting the Android 8.0 (API level 26) version of the SDK must implement one or more notification channels to post notifications to users.

  • nefgrixisnefgrixis Member ✭✭
    edited April 3

    I followed the code exactly and I don't see any notifications popping up at all.

    using Android.App;
    using Android.Content;
    using Android.Support.V4.App;
    using BizPass.Droid.Services;
    using BizPass.Util;
    using System;
    using System.Threading.Tasks;
    
    [assembly: Xamarin.Forms.Dependency(typeof(MyNotificationHandler))]
    namespace BizPass.Droid.Services
    {
        class MyNotificationHandler : INotificationHandler
        {
            public const string CHANNEL = "<ChannelName>";
            public async Task<bool> Notify(string title, string message)
            {
                NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.AppContext)
                    .SetContentTitle(title)
                    .SetContentText(message)
                    .SetSmallIcon(Resource.Drawable.icon);
                Notification notification = builder.Build();
    
                NotificationManager notManager = (NotificationManager)Application.Context.GetSystemService(Context.NotificationService);
    
                var chan = new NotificationChannel(CHANNEL, "Notification", NotificationImportance.High)
                {
                    LockscreenVisibility = NotificationVisibility.Public
                };
    
                notManager.CreateNotificationChannel(chan);
    
                const int notificationID = 0;
                notManager.Notify(notificationID, notification);
    
                return true;
            }
        }
    }
    
  • RobHouweling.4203RobHouweling.4203 USMember ✭✭
    edited April 10

    Hi,

    Running into the same issue here. NotificationAppCompat should have an channel parameter besides the context but it doesn't. Therefore it is not possible to create proper backwards compatible code.
    For Oreo and up, we now have to use the Notification.Builder:
    var notification = new Notification.Builder(ApplicationContext, PRIMARY_CHANNEL) .SetContentTitle(title).SetContentText(body).SetSmallIcon(SmallIcon);

    Older versions then Oreo have to use:
    var notification = new NotificationCompat.Builder(ApplicationContext) .SetContentTitle(title).SetContentText(body).SetSmallIcon(SmallIcon);

    @JonDouglas Can you please confirm my findings or correct me if I'm wrong?

  • RobHouweling.4203RobHouweling.4203 USMember ✭✭
    edited April 10

    After some more fiddling I think I have it working on both Oreo and below using this code:

    
    var notification = new Notification.Builder(ApplicationContext)
    .SetContentTitle(title)
    .SetContentText(body)
    .SetSmallIcon(SmallIcon);
    
    if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
    {
           notification.SetChannelId(PRIMARY_CHANNEL);
    }
    
  • JeremyBoutotJeremyBoutot Member ✭✭

    Thanks for this post. I had created a new app that targeted Oreo and couldn't for the life of me figure out why the notifications would not show in the notification area even though I was clearly receiving the message. Very helpful.

  • PaulDistonPaulDiston USUniversity ✭✭✭✭

    @JonDouglas said:
    @EricBrunner

    Only Oreo and newer versions of Android require that Notifications have proper channels defined. There are two scenarios that come in mind:

    1. Your app does not target Android 8.0 (API 26) but is ran against a device running Android 8.0 (API 26)

    This situation it will behave as if it were on <= Android 7.1 (API 25)

    1. Your app does target Android 8.0 (API 26) but is ran against a device running < Android 8.0 (API 26)

    This situation will be completely ignored as if it didn't exist. No need to worry about the current implementation breaking.

    So in both situations, your apps that are not running Android 8.0 or greater, these APIs will not be leveraged and it should remain compatible if you do or do not have Notification Channel implementations.

    @JonDouglas I am experiencing something than contradicts your comment.

    I am currently targeting Android 7.0 (API 24) and running my app on an Android 8.0 device however I am not seeing the notification appear.
    As a test, I ran the same app on an Android 6.0 (API 23) device and the notification appears successfully.

    As I am targeting Android 7.0 (API 24) I currently don't have the option in the Compat library to set the ChannelId, but by the looks of your comment, I shouldn't need to do that anyway.

    Can you shed any light on why I might be experiencing what I am?

  • PaulDistonPaulDiston USUniversity ✭✭✭✭

    @JonDouglas After further investigation it turns out that I wasn't in fact targeting Android 7.0 but Android 8.1.

    Visual Studio is slightly misleading in that for the project properties, under the Application tab, the "Compile using Android version" was set to Android 7.0, however in the Android Manifest tab, the "Target Android version" was set to Android 8.1.

    I switched the Android Manifest tab's "Target Android version" to Android 7.0 and my notifications appeared successfully.

    A side issue is the impact of upgrading the Android Manifest tab's "Target Android version" to Android 8.1 could involve upgrading Xamarin Forms and associated NuGet packages which would be a greater testing effort than just switching from GCM to FCM, which is the reason for my revisiting local notifications (local notification raised when a remote notification is received when the app is in the background) in the first place.

Sign In or Register to comment.