Una delle funzionalità che non possono mancare in una app realizzata in Unity, che sia un videogioco oppure una app non-game, è quella dell’invio di notifiche all’utente. L’uso delle notifiche aiuta nelle comunicazioni e negli eventi schedulati.
In nostro soccorso arriva il Mobile Notification Package ufficiale di Unity (consultabile qui) e installabile tramite Asset Manager. Questo pacchetto è composto da 3 parti: la gestione delle notifiche su Android, la gestione delle notifiche su iOS e la gestione delle notifiche in modo unificato (una sorta di framework trasversale tra Android e iOS che facilita la programmazione delle notifiche.
Il flusso del processo di notifica si sviluppa nei seguenti passaggi:
- Inizializzazione del centro di notifiche
- Richiesta del permesso di invio notifiche al sistema operativo
- Messa in ascolto delle notifiche ricevute (con app aperta)
- Messa in ascolto delle notifiche ricevute (con app chiusa)
- Schedulazione delle notifiche
- Cancellazione delle notifiche
E’ bene specificare che ci sono delle differenze sostanziali tra Android e iOS come ad esempio i parametri di inizializzazione (il channel così come le icone delle notifiche) che è comunque necessario differenziare in fase di progettazione.
Il consiglio è di analizzare anche la voce Project Settings -> Notification che riporta alcune funzionalità specifiche per piattaforma.
Di seguito una utile classe da istanziare in scena che permette la gestione di tutto il processo di notifica e che sfrutta in gran parte il semplice sistema unificato di Unity.
using System;
using System.Collections;
using Unity.Notifications;
using UnityEngine;
public class AppNotificationsManager : MonoBehaviour
{
private int lastNotificationResponded;
[Header("Android Notification")]
public string AndroidChannel = "default";
public string AndroidChannelName = "Notifications";
public string AndroidChannelDescription = "Main notifications";
public string AndroidIconSmall = "app_icon_small";
public string AndroidIconLarge = "app_icon_large";
public Color AndroidIconColor = Color.white;
public event Action<Notification> OnNotificationClicked;
public event Action<Notification> OnNotificationReceived;
public NotificationsPermissionRequest Permission { get; private set; }
private static AppNotificationsManager _instance;
public static AppNotificationsManager SharedInstance
{
get
{
if (_instance == null)
{
_instance = GameObject.FindFirstObjectByType<AppNotificationsManager>();
}
return _instance;
}
}
void Awake()
{
//Inizializza il canale di notifica su Android (su iOS non è necessario)
var args = NotificationCenterArgs.Default;
args.AndroidChannelId = this.AndroidChannel;
args.AndroidChannelName = this.AndroidChannelName;
args.AndroidChannelDescription = this.AndroidChannelDescription;
NotificationCenter.Initialize(args);
// Remove delivered notifications
NotificationCenter.CancelAllDeliveredNotifications();
//Notification listener
NotificationCenter.OnNotificationReceived += NotificationReceived;
}
IEnumerator Start()
{
//Permessi
Permission = NotificationCenter.RequestPermission();
if (Permission.Status == NotificationsPermissionStatus.RequestPending)
yield return Permission;
}
private void OnDestroy()
{
NotificationCenter.OnNotificationReceived -= NotificationReceived;
}
void NotificationReceived(Notification notification)
{
OnNotificationReceived?.Invoke(notification);
}
public int ScheduleNotification(string title, string text, string data, DateTime time)
{
return ScheduleNotification(title, text, data, 0, false, time);
}
public int ScheduleNotification(string title, string text, string data, int badge, bool showInForeground, DateTime time)
{
var notification = new Notification
{
Title = title,
Text = text,
Data = data,
ShowInForeground = showInForeground
};
if (badge > 0) notification.Badge = badge;
#if UNITY_ANDROID
var androidNotification = (Unity.Notifications.Android.AndroidNotification)notification;
if (!string.IsNullOrEmpty(this.AndroidIconSmall)) androidNotification.SmallIcon = this.AndroidIconSmall;
if (!string.IsNullOrEmpty(this.AndroidIconLarge)) androidNotification.LargeIcon = this.AndroidIconLarge;
androidNotification.FireTime = new NotificationDateTimeSchedule(time).FireTime;
androidNotification.Color = this.AndroidIconColor;
return Unity.Notifications.Android.AndroidNotificationCenter.SendNotification(androidNotification, this.AndroidChannel);
#else
return NotificationCenter.ScheduleNotification(notification, new NotificationDateTimeSchedule(time));
#endif
}
public void CancellAllNotifications()
{
NotificationCenter.CancelAllScheduledNotifications();
NotificationCenter.CancelAllDeliveredNotifications();
NotificationCenter.ClearBadge();
}
public void CancelNotification(int id)
{
NotificationCenter.CancelScheduledNotification(id);
NotificationCenter.CancelDeliveredNotification(id);
}
public void OpenNotificationSettings()
{
NotificationCenter.OpenNotificationSettings();
}
IEnumerator CheckForNotification()
{
var query = NotificationCenter.QueryLastRespondedNotification();
yield return query;
if (query.State == QueryLastRespondedNotificationState.HaveRespondedNotification)
{
if (lastNotificationResponded != query.Notification.Identifier.Value)
{
lastNotificationResponded = query.Notification.Identifier.Value;
OnNotificationClicked?.Invoke(query.Notification);
}
}
}
void OnApplicationFocus(bool hasFocus)
{
if (hasFocus)
{
StopCoroutine(CheckForNotification());
StartCoroutine(CheckForNotification());
}
}
void OnApplicationPause(bool paused)
{
if (!paused)
{
StopCoroutine(CheckForNotification());
StartCoroutine(CheckForNotification());
}
}
}
Una volta inizializzato il componente è possibile eseguire la funzione ScheduleNotification per programmare ad una certa data/orario l’invio della notifica dell’app:
AppNotificationsManager.SharedInstance.ScheduleNotification("Nome App","Testo della notifica", "{ eventuali dati della notifica }", DateTime.Now.AddDay(1));

