-
Notifications
You must be signed in to change notification settings - Fork 73
1. Usage 10.0.0 .Net MAUI
Elvin (Tharindu) Thudugala edited this page Aug 4, 2025
·
11 revisions
- Open your solution in Visual Studio
- Right-click on your project
- Select "Manage NuGet Packages"
- Search for "Plugin.LocalNotification"
- Select the latest version (10.0.0 or above)
- Click Install
dotnet add package Plugin.LocalNotification --version 10.0.0Install-Package Plugin.LocalNotification -Version 10.0.0The plugin requires .NET MAUI and supports both Android and iOS platforms.
Add the following permissions either through assembly attributes or in the Android Manifest.
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 permissionIn 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" />Add the following to Info.plist:
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>remote-notification</string>
</array>In MauiProgram.cs:
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseLocalNotification(); // Add this line
return builder.Build();
}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();
}// Check if notifications are enabled
if (await LocalNotificationCenter.Current.AreNotificationsEnabled() == false)
{
// Basic permission request
await LocalNotificationCenter.Current.RequestNotificationPermission();
}// 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}");
}- 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;
}
}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();
}
}
}// 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);// 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);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);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;
}
}
}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"
});
}
}For more advanced features, refer to:
- Notification Actions
- Scheduled Notifications
- Repeat Notifications
- Custom Sounds
- Location-Based Notifications
-
Missing Permissions
- Verify all required permissions are added
- Check runtime permissions for Android 13+
- Ensure battery optimization settings aren't restricting your app
-
Channel Not Found
- Ensure notification channels are created
- Check channel IDs match
- Verify channel configuration matches your requirements
-
Notifications Not Showing
- Verify Info.plist configuration
- Check notification permissions are granted
- Ensure proper provisioning profile setup
-
Background Issues
- Confirm background modes are enabled
- Check background fetch configuration
- Verify remote-notification capability
-
Package Installation
- Clean and rebuild your solution
- Check for package version conflicts
- Verify target framework compatibility
-
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.