Files
RedHotRoast-ios/Assets/TCJPLYRM1xJTSDK/ThirdParty/com.unity.mobile.notifications@2.3.2/Runtime/Unified/NotificationCenter.cs
T
2026-07-14 09:49:24 +08:00

424 lines
17 KiB
C#

using System;
#if UNITY_ANDROID
using Unity.Notifications.Android;
#else
using System.Globalization;
using Unity.Notifications.iOS;
#endif
namespace Unity.Notifications
{
/// <summary>
/// Options, specifying how notifications should be presented to the user.
/// These option can be bitwise-ored to combine them.
/// </summary>
/// <remarks>
/// On Android Alert and Sound flags are used to choose importance level for the channel, so specifying Alert also includes sound.
/// </remarks>
/// <seealso cref="NotificationCenterArgs.PresentationOptions"/>
[Flags]
public enum NotificationPresentation
{
/// <summary>
/// Specifies that when notification arrives, a pop-up should show up on screen.
/// Alerts can be disabled by user in device settings. They may also be disabled by default.
/// </summary>
Alert = 1,
/// <summary>
/// Whether notifications can set a badge on applications launcher.
/// </summary>
Badge = 1 << 1,
/// <summary>
/// Whether notifications cause device to play sound uppon arrival.
/// </summary>
Sound = 1 << 2,
/// <summary>
/// Causes device to vibrate when notification is received. Android only.
/// </summary>
Vibrate = 1 << 3,
}
/// <summary>
/// The settings section to open, if possible.
/// </summary>
public enum NotificationSettingsSection
{
/// <summary>
/// Opens settings for application and tries to open the section for notifications.
/// </summary>
Application,
/// <summary>
/// Tries to navigate to section for a particular notification category.
/// Since Android 8.0 will open notification settings for the specific notification channel.
/// </summary>
Category,
}
/// <summary>
/// Initialization arguments for <see cref="NotificationCenter"/>.
/// Recommended to use <see cref="Default"/> to retrieve recommened default values and then alter it.
/// It is required to manually set <see cref="AndroidChannelId"/>.
/// </summary>
public struct NotificationCenterArgs
{
/// <summary>
/// Returns recommended default values for all settings.
/// </summary>
public static NotificationCenterArgs Default => new NotificationCenterArgs()
{
PresentationOptions = NotificationPresentation.Badge | NotificationPresentation.Sound,
};
/// <summary>
/// Options specifying how notifications should be presented to user when they arrive.
/// On Android these only have effect if notification channel is created uppon initialization (all channel related properties are set).
/// On iOS these only have effect if permission to post notification is later requested using <see cref="NotificationCenter.RequestPermission"/>
/// </summary>
public NotificationPresentation PresentationOptions { get; set; }
/// <summary>
/// A custom non-empty string to identify notification channel. Required, Android only.
/// All notifications will be sent to this channel.
/// Channel is created automatically during initialization if <see cref="AndroidChannelName"/> and <see cref="AndroidChannelDescription"/> are both set.
/// If name and description are left null, channel with given identifier has to be created manually (for example using <see cref="AndroidNotificationCenter.RegisterNotificationChannel(AndroidNotificationChannel)"/>).
/// </summary>
public string AndroidChannelId { get; set; }
/// <summary>
/// A user visible name for notification channel. Optional, Android only.
/// Leave null, if you wish to create channel manually.
/// Set this to channel name for it to be created automatically during initialization.
/// If this is set, then <see cref="AndroidChannelDescription"/> must also be set.
/// </summary>
/// <seealso cref="AndroidChannelId"/>
public string AndroidChannelName { get; set; }
/// <summary>
/// A user visible description for the channel. Optional, Android only.
/// Leave null, if you wish to create channel manually.
/// Set this to channel description for it to be created automatically during initialization.
/// If this is set, then <see cref="AndroidChannelName"/> must also be set.
/// </summary>
/// <seealso cref="AndroidChannelId"/>
public string AndroidChannelDescription { get; set; }
}
/// <summary>
/// Send, receive and manage notifications.
/// Must be initialized before use. See <see cref="Initialize(NotificationCenterArgs)"/>.
/// </summary>
public static class NotificationCenter
{
/// <summary>
/// Delegate for <see cref="OnNotificationReceived"/>.
/// </summary>
/// <param name="notification">Notification that has been received.</param>
public delegate void NotificationReceivedCallback(Notification notification);
static bool s_Initialized = false;
static NotificationCenterArgs s_Args;
static event NotificationReceivedCallback s_OnNotificationReceived;
static bool s_OnNotificationReceivedSet = false;
#if UNITY_ANDROID
static void NotificationReceived(AndroidNotificationIntentData data)
#else
static void NotificationReceived(iOSNotification notif)
#endif
{
if (s_OnNotificationReceived != null)
{
#if UNITY_ANDROID
var notification = new Notification(data.Notification, data.Id);
#else
var notification = new Notification(notif);
#endif
s_OnNotificationReceived(notification);
}
}
/// <summary>
/// An event that fires when notification is received.
/// Application must be running for this event to work.
/// On Android this even fires if application is in foreground or when it's brought back from background.
/// On iOS this even only fires when notification is received while app is in foreground.
/// </summary>
/// <remarks>
/// This event is the same as AndroidNotificationCenter.OnNotificationReceived and iOSNotificationCenter.OnNotificationReceived.
/// </remarks>
public static event NotificationReceivedCallback OnNotificationReceived
{
add
{
if (!s_OnNotificationReceivedSet)
{
#if UNITY_ANDROID
AndroidNotificationCenter.OnNotificationReceived += NotificationReceived;
#else
iOSNotificationCenter.OnNotificationReceived += NotificationReceived;
#endif
s_OnNotificationReceivedSet = true;
}
s_OnNotificationReceived += value;
}
remove
{
s_OnNotificationReceived -= value;
}
}
/// <summary>
/// Initializes notification center with given arguments.
/// On Android it will also create notification channel if arguments are set accordingly.
/// </summary>
/// <param name="args">Arguments for initialization.</param>
public static void Initialize(NotificationCenterArgs args)
{
if (s_Initialized)
return;
if (string.IsNullOrEmpty(args.AndroidChannelId))
throw new ArgumentException("AndroidChannel not provided");
s_Args = args;
s_Initialized = true;
#if UNITY_ANDROID
AndroidNotificationCenter.Initialize();
if (args.AndroidChannelName != null || args.AndroidChannelDescription != null)
{
Importance importance = Importance.Low;
if (0 != (args.PresentationOptions & NotificationPresentation.Alert))
importance = Importance.High;
else if (0 != (args.PresentationOptions & NotificationPresentation.Sound))
importance = Importance.Default;
AndroidNotificationCenter.RegisterNotificationChannel(new AndroidNotificationChannel()
{
Id = args.AndroidChannelId,
Name = args.AndroidChannelName,
Description = args.AndroidChannelDescription,
Importance = importance,
CanShowBadge = 0 != (args.PresentationOptions & NotificationPresentation.Badge),
EnableVibration = 0 != (args.PresentationOptions & NotificationPresentation.Vibrate),
});
}
#endif
}
/// <summary>
/// Request for users permission to post notifications.
/// Requests users permission to send notifications. Unless already allowed or permanently denied, shows UI to the user.
/// Users can revoke permission in Settings while app is not running.
/// </summary>
/// <returns>An object for tracking the request and obtaining results.</returns>
/// <remarks>Before Android 13 no permission is required.</remarks>
public static NotificationsPermissionRequest RequestPermission()
{
CheckInitialized();
int iOSAuthorizationOptions = 0;
#if UNITY_IOS
if (0 != (s_Args.PresentationOptions & NotificationPresentation.Alert))
iOSAuthorizationOptions |= (int)AuthorizationOption.Alert;
if (0 != (s_Args.PresentationOptions & NotificationPresentation.Badge))
iOSAuthorizationOptions |= (int)AuthorizationOption.Badge;
if (0 != (s_Args.PresentationOptions & NotificationPresentation.Sound))
iOSAuthorizationOptions |= (int)AuthorizationOption.Sound;
#endif
return new NotificationsPermissionRequest(iOSAuthorizationOptions);
}
static void CheckInitialized()
{
if (!s_Initialized)
throw new Exception("NotificationCenter not initialized");
}
/// <summary>
/// Schedule notification to be shown in the future.
/// </summary>
/// <typeparam name="T">Type of the schedule, usually deduced from actually passed one.</typeparam>
/// <param name="notification">Notification to send.</param>
/// <param name="schedule">Schedule, specifying, when notification should be shown.</param>
/// <returns>Notification identifier.</returns>
public static int ScheduleNotification<T>(Notification notification, T schedule)
where T : NotificationSchedule
{
string category = null;
#if UNITY_ANDROID
category = s_Args.AndroidChannelId;
#endif
return ScheduleNotification(notification, category, schedule);
}
/// <summary>
/// Schedule notification to be shown in the future.
/// Allows to explicitly specify the category to send notification to. On Android it is notification channel.
/// Channel or category has to be created manually using AndroidNotificationCenter and iOSNotificationCenter respectively.
/// </summary>
/// <typeparam name="T">Type of the schedule, usually deduced from actually passed one.</typeparam>
/// <param name="notification">Notification to send.</param>
/// <param name="category">Identifier for iOS category or Android channel.</param>
/// <param name="schedule">Schedule, specifying, when notification should be shown.</param>
/// <returns>Notification identifier.</returns>
public static int ScheduleNotification<T>(Notification notification, string category, T schedule)
where T : NotificationSchedule
{
CheckInitialized();
#if UNITY_ANDROID
var n = (AndroidNotification)notification;
schedule.Schedule(ref n);
if (notification.Identifier.HasValue)
{
AndroidNotificationCenter.SendNotificationWithExplicitID(n, category, notification.Identifier.Value);
return notification.Identifier.Value;
}
else
return AndroidNotificationCenter.SendNotification(n, category);
#else
var n = (iOSNotification)notification;
if (n == null)
throw new ArgumentException("Passed notifiation is empty");
n.CategoryIdentifier = category;
schedule.Schedule(ref n);
iOSNotificationCenter.ScheduleNotification(n);
if (notification.Identifier.HasValue)
return notification.Identifier.Value;
// iOSNotification is class and has auto-generated id set at this point
// for consistency with Android set it back to null, so same Notification can be sent again as new one
int id = int.Parse(n.Identifier, NumberStyles.None, CultureInfo.InvariantCulture);
n.Identifier = null;
return id;
#endif
}
/// <summary>
/// Returns last notification tapped by user, or null.
/// </summary>
public static Notification? LastRespondedNotification
{
get
{
CheckInitialized();
#if UNITY_ANDROID
var intent = AndroidNotificationCenter.GetLastNotificationIntent();
if (intent == null)
return null;
return new Notification(intent.Notification, intent.Id);
#else
var notification = iOSNotificationCenter.GetLastRespondedNotification();
if (notification == null)
return null;
return new Notification(notification);
#endif
}
}
/// <summary>
/// Cancel a scheduled notification.
/// </summary>
/// <param name="id">ID of the notification to cancel.</param>
public static void CancelScheduledNotification(int id)
{
CheckInitialized();
#if UNITY_ANDROID
AndroidNotificationCenter.CancelScheduledNotification(id);
#else
iOSNotificationCenter.RemoveScheduledNotification(id.ToString(CultureInfo.InvariantCulture));
#endif
}
/// <summary>
/// Cancel delivered notification.
/// Removes notification from the tray.
/// </summary>
/// <param name="id">ID of the notification to cancel.</param>
public static void CancelDeliveredNotification(int id)
{
CheckInitialized();
#if UNITY_ANDROID
AndroidNotificationCenter.CancelDisplayedNotification(id);
#else
iOSNotificationCenter.RemoveDeliveredNotification(id.ToString(CultureInfo.InvariantCulture));
#endif
}
/// <summary>
/// Cancel all future notifications.
/// </summary>
public static void CancelAllScheduledNotifications()
{
CheckInitialized();
#if UNITY_ANDROID
AndroidNotificationCenter.CancelAllScheduledNotifications();
#else
iOSNotificationCenter.RemoveAllScheduledNotifications();
#endif
}
/// <summary>
/// Remove all already delivered notifications.
/// </summary>
public static void CancelAllDeliveredNotifications()
{
CheckInitialized();
#if UNITY_ANDROID
AndroidNotificationCenter.CancelAllDisplayedNotifications();
#else
iOSNotificationCenter.RemoveAllDeliveredNotifications();
#endif
}
/// <summary>
/// Clear Application badge. iOS only.
/// iOS applications can set numeric badge on app icon. Calling this method removes that badge.
/// On Android badge is removed automatically when notifications are removed.
/// </summary>
public static void ClearBadge()
{
CheckInitialized();
#if UNITY_IOS
iOSNotificationCenter.ApplicationBadge = 0;
#endif
}
/// <summary>
/// Opens settings for the application.
/// If possible, will try to navigate as close to requested section as it can.
/// On iOS and Android prior to 8.0 will open settings for the application.
/// Since Android 8.0 will open notification settings for either application or the default channel.
/// </summary>
/// <param name="section">The section to navigate to.</param>
public static void OpenNotificationSettings(NotificationSettingsSection section = NotificationSettingsSection.Application)
{
CheckInitialized();
#if UNITY_ANDROID
string channel = section switch
{
NotificationSettingsSection.Category => s_Args.AndroidChannelId,
NotificationSettingsSection.Application => null,
_ => null,
};
AndroidNotificationCenter.OpenNotificationSettings(channel);
#else
iOSNotificationCenter.OpenNotificationSettings();
#endif
}
}
}