Skip to content

1. Usage 10.0.0 .Net MAUI

Elvin (Tharindu) Thudugala edited this page Aug 4, 2025 · 11 revisions

.NET MAUI Local Notifications Guide

Installation

Installation Options

1. Using NuGet Package Manager UI

  1. Open your solution in Visual Studio
  2. Right-click on your project
  3. Select "Manage NuGet Packages"
  4. Search for "Plugin.LocalNotification"
  5. Select the latest version (10.0.0 or above)
  6. Click Install

2. Using .NET CLI

dotnet add package Plugin.LocalNotification --version 10.0.0

3. Using Package Manager Console

Install-Package Plugin.LocalNotification -Version 10.0.0

The plugin requires .NET MAUI and supports both Android and iOS platforms.

Platform Configuration

Android Setup

Required Permissions

Add the following permissions either through assembly attributes or in the Android Manifest.

Option 1: Assembly Attributes

In Platforms/Android/MainApplication.cs, add:

// Essential permissions
[assembly: UsesPermission(Manifest.Permission.Vibrate)]
[assembly: UsesPermission(Manifest.Permission.POST_NOTIFICATIONS)]
[assembly: UsesPermission(Manifest.Permission.WAKE_LOCK)]
[assembly: UsesPermission(Manifest.Permission.RECEIVE_BOOT_COMPLETED)]

// Optional: For exact timing in Calendar/Alarm apps (Android 14+)
[assembly: UsesPermission("android.permission.USE_EXACT_ALARM")] // No user prompt, requires Android 13+
[assembly: UsesPermission("android.permission.SCHEDULE_EXACT_ALARM")] // User can grant permission
Option 2: Android Manifest

In Platforms/Android/AndroidManifest.xml, add:

<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<!-- Optional: For exact timing -->
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" android:maxSdkVersion="32" />

iOS Setup

Add the following to Info.plist:

<key>UIBackgroundModes</key>
<array>
    <string>fetch</string>
    <string>remote-notification</string>
</array>

Application Setup

Basic Initialization

In MauiProgram.cs:

public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        .UseLocalNotification(); // Add this line

    return builder.Build();
}

Advanced Configuration

public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        .UseLocalNotification(config =>
        {
            // Configure Android channels
            config.AddAndroid(android =>
            {
                android.AddChannel(new NotificationChannelRequest
                {
                    Id = "general",
                    Name = "General",
                    Description = "General notifications"
                });
            });

            // Configure iOS settings
            config.AddiOS(ios =>
            {
#if IOS
                ios.SetCustomUserNotificationCenterDelegate(
                    new CustomUserNotificationCenterDelegate()
                );
#endif
            });

            // Configure serialisation if needed
            config.SetSerializer(new MyCustomSerializer());
        });
            
    return builder.Build();
}

Permission Management and Verification

Basic Permission Request

// Check if notifications are enabled
if (await LocalNotificationCenter.Current.AreNotificationsEnabled() == false)
{
    // Basic permission request
    await LocalNotificationCenter.Current.RequestNotificationPermission();
}

Advanced Permission Configuration

// Request with specific options
var permissionRequest = new NotificationPermission
{
    // iOS-specific settings
    iOS = 
    {
        // Configure authorisation options
        NotificationAuthorization = iOSAuthorizationOptions.Alert | 
                             iOSAuthorizationOptions.Badge | 
                             iOSAuthorizationOptions.Sound,
        
        // Configure location authorisation (if using geofencing)
        LocationAuthorization = iOSLocationAuthorization.Always
    },
    
    // Android-specific settings
    Android =
    {
        // indicating whether to request permission to schedule exact alarms (for scheduled notifications)
        RequestPermissionToScheduleExactAlarm = true
    }
};

try
{
    var result = await LocalNotificationCenter.Current.RequestNotificationPermission(permissionRequest);
    
    if (!result)
    {       
        // Handle permission denial
        Debug.WriteLine("Notification permissions denied");
        
        // Optionally guide user to settings
        if (DeviceInfo.Platform == DevicePlatform.iOS)
        {
            await Launcher.OpenAsync("app-settings:");
        }
        else if (DeviceInfo.Platform == DevicePlatform.Android)
        {
            await Launcher.OpenAsync(new Uri("package:com.yourapp.package"));
        }
    }
}
catch (Exception ex)
{
    // Handle permission request errors
    Debug.WriteLine($"Permission request failed: {ex.Message}");
}

Permission Best Practices

Timing and User Experience

  • Request permissions at appropriate moments
  • Explain why permissions are needed
  • Consider using a "soft ask" approach
public class NotificationPermissionManager
{
    private readonly IPreferences _preferences;
    
    public async Task<bool> RequestPermissionsWithSoftAsk()
    {
        // Check if we've shown the soft ask
        if (!_preferences.Get("has_shown_notification_prompt", false))
        {
            // Show custom UI explaining why notifications are needed
            var shouldRequest = await ShowCustomPermissionDialog();
            
            if (!shouldRequest)
            {
                _preferences.Set("has_shown_notification_prompt", true);
                return false;
            }
        }
        
        // Proceed with actual permission request
        var result = await LocalNotificationCenter.Current.RequestNotificationPermission();
        return result;
    }
}

Graceful Degradation

public async Task HandlePermissionDenial()
{
    // Check if permissions can be requested again
    var status = await LocalNotificationCenter.Current.AreNotificationsEnabled();
    
    if (!status)
    {
        // Show dialogue explaining impact
        var shouldOpenSettings = await ShowPermissionDeniedDialog();
        
        if (shouldOpenSettings)
        {
            // Guide user to app settings
            await OpenAppSettings();
        }
        else
        {
            // Enable alternative features
            EnableAlternativeFeatures();
        }
    }
}

Setup Verification

// Send a test notification
var notification = new NotificationRequest
{
    NotificationId = 1,
    Title = "Setup Test",
    Description = "If you see this, setup was successful!"
};
await LocalNotificationCenter.Current.Show(notification);

Usage Examples

Basic Notification

// Check/Request Permissions
if (await LocalNotificationCenter.Current.AreNotificationsEnabled() == false)
{
    await LocalNotificationCenter.Current.RequestNotificationPermission();
}

// Create and show notification
var notification = new NotificationRequest
{
    NotificationId = 100,
    Title = "Notification Title",
    Description = "This is the notification message",
    ReturningData = "custom-data" // Data to return when notification is tapped
};
await LocalNotificationCenter.Current.Show(notification);

Scheduled Notification

var scheduledNotification = new NotificationRequest
{
    NotificationId = 101,
    Title = "Reminder",
    Description = "Don't forget your appointment!",
    Schedule = 
    {
        NotifyTime = DateTime.Now.AddHours(2) // Schedule 2 hours from now
    }
};
await LocalNotificationCenter.Current.Show(scheduledNotification);

Handling Notification Events

In your App.xaml.cs:

public partial class App : Application
{
    public App()
    {
        InitializeComponent();

        // Subscribe to notification events
        LocalNotificationCenter.Current.NotificationActionTapped += OnNotificationActionTapped;

        MainPage = new MainPage();
    }
    
    private void OnNotificationActionTapped(NotificationActionEventArgs e)
    {
        if (e.IsDismissed)
        {
            // Handle notification dismissal
            return;
        }

        if (e.IsTapped)
        {
            // Handle notification tap
            var returnedData = e.Request.ReturningData;
            // Process the returned data
            return;
        }

        // Handle notification actions if configured
        switch (e.ActionId)
        {
            case 1:
                // Handle action 1
                break;
            case 2:
                // Handle action 2
                break;
        }
    }
}

MVVM Pattern Support

The plugin supports dependency injection. Instead of using LocalNotificationCenter.Current, you can inject INotificationService:

public class YourViewModel
{
    private readonly INotificationService _notificationService;

    public YourViewModel(INotificationService notificationService)
    {
        _notificationService = notificationService;
    }

    public async Task ShowNotification()
    {
        await _notificationService.Show(new NotificationRequest
        {
            NotificationId = 100,
            Title = "MVVM Notification",
            Description = "This notification was triggered from a ViewModel"
        });
    }
}

Additional Features

For more advanced features, refer to:

Troubleshooting

Android Issues

  1. Missing Permissions

    • Verify all required permissions are added
    • Check runtime permissions for Android 13+
    • Ensure battery optimization settings aren't restricting your app
  2. Channel Not Found

    • Ensure notification channels are created
    • Check channel IDs match
    • Verify channel configuration matches your requirements

iOS Issues

  1. Notifications Not Showing

    • Verify Info.plist configuration
    • Check notification permissions are granted
    • Ensure proper provisioning profile setup
  2. Background Issues

    • Confirm background modes are enabled
    • Check background fetch configuration
    • Verify remote-notification capability

Build Issues

  1. Package Installation

    • Clean and rebuild your solution
    • Check for package version conflicts
    • Verify target framework compatibility
  2. Runtime Errors

    • Enable detailed logging for debugging
    • Check application output for error messages
    • Verify all platform-specific setup steps

For more troubleshooting tips and standard solutions, see the FAQ.

Clone this wiki locally