Unity 定时发送通知

unity.jpeg

这里用到的插件是Pakeage Manager中的Moblie Notification。


Mobile Notifications.png

建议用推荐版本version1.0.3,下载成功之后,Package包下会自动生成如下图:


20211207094654.jpg

创建一个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");
    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容