转自:
http://taoyuannote.com/2016/02/18/blog/Unity3D%E6%B8%B8%E6%88%8F%E4%B8%ADAndroid%E5%92%8CiOS%E6%9C%AC%E5%9C%B0%E6%8E%A8%E9%80%81%E9%80%9A%E7%9F%A5/
unity-android-notifications Demo
概述
在Unity3D手游中,有时会遇到定时通知的需求,比如通知用户每天中午和晚上
固定时间领取体力,或者每周1、3、5在某个时间点去参加某某活动等。这种需求因为是固定的时间就可以推送,所以不需要通过服务器来进行推送,只需要利用各个平台自己的本地推送机制就可以实现这个功能。在这里,我们讨论iOS和Android两个平台的实现。由于Unity3D官方已经帮我们实现了iOS端的本地推送的实现,所以我们在编写iOS推送时就使用Unity3D帮我们实现的接口就可以了。对于Android端,Unity3D并没有提供现成的接口,所以我们采用的是GitHub上找到的第三方的推送接口。
iOS端推送
Unity3D给我们提供了一个类LocalNotification,通过此类就可以实现iOS的本地推送通知。下面简单介绍这个类常用的一些属性:
- fireData. 这个属性是推送的时间,类型是一个DateTime。
- alertBody. 这个属性是通知消息的正文。
- applicationIconBadgeNumber. 游戏Icon上的角标上显示通知的数量。
- repeatCalendar. 循环播放通知时所依据的日历类型(比如UTC,chinese).
- repeatInterval. 循环播放时的播放间隔。
下面再介绍几个常用的方法。
1
| public static void RegisterForNotifications(iOS.NotificationType notificationTypes);
|
在高版本的iOS(ios8及以后)中,如果想要推送本地消息,就需要通过这个方法向用户申请推送的权限。 NotificationType有4个值,分别是None,Badge,Sound,Alert.意思分别为None,角标,声音和提醒。一般会都选。
1
| public static void ScheduleLocalNotification(iOS.LocalNotification notification);
|
当你填好推送的条件之后,利用这个方法可以把推送消息注册到系统中。
1 2 | public static void CancelLocalNotification(iOS.LocalNotification notification); public static void CancelAllLocalNotifications(); |
这两个方法都可以取消一个推送通知,第一个是取消一个推送,第二个是取消所有的推送通知。
1
| public static void ClearLocalNotifications();
|
这个方法可以清除下拉栏中的通知。
Android本地推送
Android将通过一个第三方库来完成本地通知。库GitHub地址点此。
通过这个第三方库,我们可以很轻松的实现Android的本地推送。下面我们看几个常用方法:
1 2 3 4 5 | public static void SendNotification(int id, TimeSpan delay, string title, string message); public static void SendNotification(int id, long delay, string title, string message, Color32 bgColor, bool sound = true, bool vibrate = true, bool lights = true, string bigIcon = "", NotificationExecuteMode executeMode = NotificationExecuteMode.Inexact); public static void SendRepeatingNotification(int id, long delay, long timeout, string title, string message, Color32 bgColor, bool sound = true, bool vibrate = true, bool lights = true, string bigIcon = ""); |
这三个重载方法都是用来定义localnotification的,前两个方法都是定义一个一次性的通知,区别只是一些参数有些变化。第三个方法用来定义循环推送。方法的第一个参数id指的是notification的编号,不能重复,第二个参数delay指的是延迟时间(比如5秒后触发),第三个参数timeout是指下次触发时间(比如第一次触发在5秒后,然后每天重复一次,那么第二次触发时间就是“当前时间” + 5s + 24 x 60 x 60秒后触发),第四个参数title是notification的标题,第五个参数是消息内容,之后的方法根据名字就可以看出来了,就不一一介绍了。
1
| public static void CancelNotification(int id);
|
通过这个方法可以取消一个推送通知。所以我们需要保存之前创建notification的编号,以方便取消。
下面我们用这些方法实现上面iOS同样功能的推送通知。
示例
上面这个示例中,用UNITY_IPHONE包围起来的是iOS平台相关代码,用UNITY_ANDROID包围起来的是Android平台相关代码。除了以下代码外,推送还需要注意以下几点:
- Android推送需要在manifest文件中加入一些权限,具体请参考Android第三方库中示例工程。
- 推送的时间点应该以服务器为主,当游戏采取全球发行时,就需要谨慎处理时区问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
using UnityEngine; using System.Collections; #if UNITY_IPHONE using NotificationServices = UnityEngine.iOS.NotificationServices; using NotificationType = UnityEngine.iOS.NotificationType; #endif public class NewBehaviourScript : MonoBehaviour { //本地推送 public static void NotificationMessage(string message,int hour ,bool isRepeatDay) { int year = System.DateTime.Now.Year; int month = System.DateTime.Now.Month; int day= System.DateTime.Now.Day; System.DateTime newDate = new System.DateTime(year,month,day,hour,0,0); NotificationMessage(message,newDate,isRepeatDay); } //本地推送 你可以传入一个固定的推送时间 public static void NotificationMessage(string message,System.DateTime newDate,bool isRepeatDay) { #if UNITY_IPHONE //推送时间需要大于当前时间 if(newDate > System.DateTime.Now) { UnityEngine.iOS.LocalNotification localNotification = new UnityEngine.iOS.LocalNotification(); localNotification.fireDate =newDate; localNotification.alertBody = message; localNotification.applicationIconBadgeNumber = 1; localNotification.hasAction = true; localNotification.alertAction = "这是notificationtest的标题"; if(isRepeatDay) { //是否每天定期循环 localNotification.repeatCalendar = UnityEngine.iOS.CalendarIdentifier.ChineseCalendar; localNotification.repeatInterval = UnityEngine.iOS.CalendarUnit.Day; } localNotification.soundName = UnityEngine.iOS.LocalNotification.defaultSoundName; UnityEngine.iOS.NotificationServices.ScheduleLocalNotification(localNotification); } #endif #if UNITY_ANDROID if (newDate > System.DateTime.Now) { LocalNotification.SendNotification(1,10,"这是notificationtest的标题","这是notificationtest的消息",new Color32(0xff, 0x44, 0x44, 255)); if (System.DateTime.Now.Hour >= 12) { //System.DateTime dataTimeNextNotify = new System.DateTime( long delay = 24 * 60 * 60 - ((System.DateTime.Now.Hour - 12)* 60 * 60 + System.DateTime.Now.Minute * 60 + System.DateTime.Now.Second); LocalNotification.SendRepeatingNotification(2,delay, 24 * 60 * 60,"这是notificationtest的标题","每天中午12点推送",new Color32(0xff, 0x44, 0x44, 255)); } else { long delay = (12 - System.DateTime.Now.Hour)* 60 * 60 - System.DateTime.Now.Minute * 60 - System.DateTime.Now.Second; LocalNotification.SendRepeatingNotification(2,delay,24 * 60 * 60 ,"这是notificationtest的标题","每天中午12点推送",new Color32(0xff, 0x44, 0x44, 255)); } } #endif } void Awake() { #if UNITY_IPHONE UnityEngine.iOS.NotificationServices.RegisterForNotifications ( NotificationType.Alert | NotificationType.Badge | NotificationType.Sound); #endif //第一次进入游戏的时候清空,有可能用户自己把游戏冲后台杀死,这里强制清空 CleanNotification(); } void OnApplicationPause(bool paused) { //程序进入后台时 if(paused) { //10秒后发送 NotificationMessage("这是notificationtest的推送正文信息",System.DateTime.Now.AddSeconds(10),false); //每天中午12点推送 NotificationMessage("每天中午12点推送",12,true); } else { //程序从后台进入前台时 CleanNotification(); } } //清空所有本地消息 void CleanNotification() { #if UNITY_IPHONE UnityEngine.iOS.LocalNotification l = new UnityEngine.iOS.LocalNotification (); l.applicationIconBadgeNumber = -1; UnityEngine.iOS.NotificationServices.PresentLocalNotificationNow (l); UnityEngine.iOS.NotificationServices.CancelAllLocalNotifications (); UnityEngine.iOS.NotificationServices.ClearLocalNotifications (); #endif #if UNITY_ANDROID LocalNotification.CancelNotification(1); LocalNotification.CancelNotification(2); #endif } }
参考
LocalNotification
NotificationServices
Unity3D研究院之IOS本地消息通知LocalNotification的使用(六十七)
unity-android-notifications