这里用到的插件是Pakeage Manager中的Moblie Notification。
建议用推荐版本version1.0.3,下载成功之后,Package包下会自动生成如下图:
创建一个NotificationSender
控制不同平台下,使用AndroidNotificationSender和iOSNotificationSender。
public class NotificationInfo
{
public string title;
public string text;
public int day;
public int hour;
public int minute;
public int second;
public string smallIcon;
public string largeIcon;
}
public class NotificationSender:
#if UNITY_ANDROID
AndroidNotificationSender
#else
iOSNotificationSender
#endif
{
private void OnApplicationFocus(bool hasFocus)
{
if(hasFocus)
ReSendNotification();
}
/// <summary>
/// 得到注册通知的时间
/// </summary>
/// <returns></returns>
public static DateTime GetNotificationTime(NotificationInfo notificationInfo)
{
var daySpan = new TimeSpan(notificationInfo.day,notificationInfo.hour,notificationInfo.minute,notificationInfo.second);
var dateTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second) ;
dateTime += daySpan;
if (dateTime.Hour >= 23)
{
dateTime += new TimeSpan(9, 0, 0);
}
if (dateTime.Hour <= 8)
{
dateTime += new TimeSpan(8 - dateTime.Hour, 0, 0);
}
// Debug.Log("LinneaNotify 发出通知时间 : " + dateTime);
return dateTime;
}
}
限制了通知时间,不得23点之后和8点之前发出。
Android平台代码:
#if UNITY_ANDROID
using System;
using System.Collections.Generic;
using Unity.Notifications.Android;
using UnityEngine;
public class AndroidNotificationSender:MonoBehaviour
{
private static bool _isInitialized;
private static List<NotificationInfo> _notificationInfos;
private static int _notificationId = 19991;
private static void Init()
{
if(_isInitialized)
return;
_notificationInfos = new List<NotificationInfo>();
ResetNotificationChannel();
var notificationGo= new GameObject("NotificationBehaviour").AddComponent<NotificationSender>();
DontDestroyOnLoad(notificationGo);
_isInitialized = true;
}
private static void ResetNotificationChannel()
{
_notificationId = 19991;
AndroidNotificationCenter.CancelAllNotifications();//清除上次注册的通知
var channel = new AndroidNotificationChannel()
{
Id = "channel_id",
Name = "Default Channel",
Importance = Importance.High,
Description = "Generic notifications",
CanShowBadge = true,
EnableLights=true,
LockScreenVisibility=LockScreenVisibility.Public
};
AndroidNotificationCenter.RegisterNotificationChannel(channel);
}
protected static void ReSendNotification()
{
if (_isInitialized && _notificationInfos != null && _notificationInfos.Count > 0)
{
ResetNotificationChannel();
// for (var i = 0; i < _notificationInfos.Count; i++)
// {
// SendNotification(_notificationInfos[i]);
// }
}
}
/// <summary>
/// Android 发送通知
/// </summary>
/// <param name="title"></param>
/// <param name="text"></param>
/// <param name="day"></param>
/// <param name="hour"></param>
/// <param name="minute"></param>
/// <param name="second"></param>
/// <param name="smallIconId"></param>
/// <param name="largeIconId"></param>
public static void SendNotification(string title, string text,int day,int hour,int minute,int second ,string smallIconId=null,string largeIconId=null)
{
Init();
var notificationInfo = new NotificationInfo()
{
title = title,
text = text,
day = day,
hour = hour,
minute = minute,
second = second,
smallIcon = smallIconId,
largeIcon = largeIconId
};
_notificationInfos.Add(notificationInfo);
SendNotification(notificationInfo);
}
private static void SendNotification(NotificationInfo notificationInfo)//string title, string text,DateTime time,string smallIconId=null,string largeIconId=null)
{
var time = NotificationSender.GetNotificationTime(notificationInfo);
var notification = new AndroidNotification(){
Title = notificationInfo.title,
Text = notificationInfo.text,
FireTime = time,
SmallIcon = notificationInfo.smallIcon,
LargeIcon = notificationInfo.largeIcon,
Number = _notificationId
};
AndroidNotificationCenter.CancelNotification(_notificationId);
_notificationId++;
AndroidNotificationCenter.SendNotification(notification, "channel_id");
}
}
#endif
注意ReSendNotification方法,因为我在外部限制通知每次发出先判断上次是否还有通知未发出,所以屏蔽了ReSend方法 。
IOS平台代码:
#if UNITY_IOS
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Notifications.iOS;
public class iOSNotificationSender:MonoBehaviour
{
private static bool _isInitialized = false;
private static int _notificationId = 1;
private static List<NotificationInfo> _notificationInfos;
// Start is called before the first frame update
private static void Init()
{
if(_isInitialized)
return;
_notificationInfos = new List<NotificationInfo>();
ResetNotificationChannel();
var notificationGo= new GameObject("NotificationBehaviour").AddComponent<NotificationSender>();
DontDestroyOnLoad(notificationGo);
_isInitialized = true;
}
private static void ResetNotificationChannel()
{
_notificationId = 1;
iOSNotificationCenter.ApplicationBadge=0;
iOSNotificationCenter.RemoveAllDeliveredNotifications();
iOSNotificationCenter.RemoveAllScheduledNotifications();
}
protected static void ReSendNotification()
{
if (_isInitialized&&_notificationInfos!=null && _notificationInfos.Count > 0)
{
ResetNotificationChannel();
// for (var i = 0; i < _notificationInfos.Count; i++)
// {
// SendNotification(_notificationInfos[i]);
// }
}
}
/// <summary>
/// 发送通知方法
/// </summary>
/// <param name="title"></param>
/// <param name="text"></param>
/// <param name="day"></param>
/// <param name="hour"></param>
/// <param name="minute"></param>
/// <param name="second"></param>
/// <param name="smallIconId"></param>
/// <param name="largeIconId"></param>
public static void SendNotification(string title, string text,int day,int hour,int minute,int second ,string smallIconId=null,string largeIconId=null)
{
Init();
var notificationInfo = new NotificationInfo()
{
title = title,
text=text,
day=day,
hour = hour,
minute = minute,
second = second,
smallIcon = smallIconId,
largeIcon = largeIconId
};
_notificationInfos.Add(notificationInfo);
SendNotification(notificationInfo);
}
private static void SendNotification(NotificationInfo notificationInfo)//string title, string text,TimeSpan timeInterval)
{
var time = NotificationSender.GetNotificationTime(notificationInfo);
var timeInterval = time.Subtract(DateTime.Now);
var timeTrigger = new iOSNotificationTimeIntervalTrigger()
{
TimeInterval = new TimeSpan(timeInterval.Days, timeInterval.Hours, timeInterval.Minutes, timeInterval.Seconds),// timeInterval,
Repeats = false
};
var notification = new iOSNotification()
{
Identifier = "_notification_"+ _notificationId,
Title = notificationInfo.title,
Body = notificationInfo.text,
Badge = _notificationId,
ShowInForeground = true,
ForegroundPresentationOption = (PresentationOption.Alert | PresentationOption.Sound | PresentationOption.Badge),
CategoryIdentifier = "category_a",
ThreadIdentifier = "thread1",
Trigger = timeTrigger,
};
_notificationId++;
iOSNotificationCenter.ScheduleNotification(notification);
}
}
#endif
注意_notificationId,这里的id实际上是显示在AppIcon的红点数字
我的调用处理,在程序退出后台后,判断是否达到条件,是否要发出通知:
/// <summary>
/// isPause
/// </summary>
private static bool isPause;
private static bool isSendNearNotify;
private static bool isSendFarNotify;
private void OnApplicationPause(bool pauseStatus)
{
isPause = pauseStatus;
if (isPause)
{
JudgeNearNotify();
JudgeFarNotify();
}
else
{
isSendNearNotify = false;
isSendFarNotify = false;
}
}
发出一条近期带活通知:
private static void JudgeNearNotify()
{
if (!isPause || isSendNearNotify) return;
isSendNearNotify = true;
var title = LocalizationManager.GetTranslation("notify_title1");
var text = LocalizationManager.GetTranslation("notify_content1");
var time1 = OfflineEquipment.Instance.GetNotifyOfflineTime();
var time2 = CropManager.Instance.GetNotifyCropTime();
var max = time1;
// Debug.Log("LinneaNotify time1 = " + time1 + ", time2 = " + time2);
if (time2 > time1)
{
title = LocalizationManager.GetTranslation("notify_title2");
text = LocalizationManager.GetTranslation("notify_content2");
max = time2;
}
if (max > 0)
{
var day = max / 60 / 60 / 24;
var hour = max / 60 / 60 % 24;
var minute = max / 60 % 60;
var second = max % 60;
// Debug.Log("LinneaNotify day = " + day + ", hour = " + hour + ", minute = " + minute + ", sec = " + second);
NotificationSender.SendNotification(title, text, day, hour, minute, second, "icon_large");
}
}
发出一条远期带活通知:
/// <summary>
/// 长期不在线拉活
/// </summary>
private static void JudgeFarNotify()
{
if (!isPause || isSendFarNotify) return;
isSendNearNotify = true;
var title = LocalizationManager.GetTranslation("notify_title3");
var text = LocalizationManager.GetTranslation("notify_content3");
NotificationSender.SendNotification(title, text, 3, 0, 0, 0, "icon_large");
}