unity3d 之本地推送
参考:http://blog.csdn.net/azhou_hui/article/details/50790870
1. 本地推送主要包括在android和ios上,下面所有的代码都是本人写的,经过测试是没有问题的,已经运用到项目中了。首先是接口INotification:
- using System;
- public interface INotification : IDisposable
- {
- /// <summary>
- /// 注册一个推送
- /// </summary>
- /// <param name="id">消息唯一标识</param>
- /// <param name="name">消息弹出一时在手机屏幕最上方显示的文字,对苹果无效</param>
- /// <param name="title">通知栏中消息的标题</param>
- /// <param name="content">通知栏中消息的正文</param>
- /// <param name="triggerTime">触发的时间</param>
- /// <param name="repeat">是否要每日重复触发</param>
- void Register(int id, string name, string title, string content, DateTime triggerTime, bool repeat);
- /// <summary>
- /// 取消一个推送
- /// </summary>
- /// <param name="id">消息唯一标识</param>
- void Unregister(int id);
- /// <summary>
- /// 取消所有推送
- /// </summary>
- void ClearAll();
- }
INotification
2. android的实现:
- #if UNITY_ANDROID
- using System;
- using UnityEngine;
- public class AndroidNotification : INotification
- {
- AndroidJavaObject m_javaObj = new AndroidJavaObject("com.example.localpush.AlarmReceiver");
- public void Register(int id, string name, string title, string content, DateTime triggerTime, bool repeat)
- {
- int secondsFromNow = (int)(triggerTime - DateTime.Now).TotalSeconds;
- m_javaObj.CallStatic("Register", new object[]
- {
- id,
- name,
- title,
- content,
- secondsFromNow,
- repeat
- });
- }
- public void Unregister(int id)
- {
- m_javaObj.CallStatic("Unregister", id);
- }
- public void ClearAll()
- {
- var types = Enum.GetValues(typeof(NotificationType));
- for (int i = ; i < types.Length * ; i++)
- Unregister(i);
- }
- #region IDisposable
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- m_javaObj.Dispose();
- m_javaObj = null;
- }
- }
- ~AndroidNotification()
- {
- Dispose(false);
- }
- #endregion
- }
- #endif
AndroidNotification
其中 "com.example.localpush.AlarmReceiver" 中的java代码如下:
- package com.example.localpush;
- import java.util.ArrayList;
- import java.util.Calendar;
- import android.app.Activity;
- import android.app.AlarmManager;
- import android.app.Notification;
- import android.app.NotificationManager;
- import android.app.PendingIntent;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.SharedPreferences;
- import android.content.SharedPreferences.Editor;
- import android.content.pm.ApplicationInfo;
- import android.content.pm.PackageManager;
- import android.content.pm.PackageManager.NameNotFoundException;
- import android.util.Log;
- import com.unity3d.player.UnityPlayer;
- public class AlarmReceiver extends BroadcastReceiver
- {
- static final int NotificationCount = 10;
- static final int RepeatInterval = 24 * 60 * 60 * 1000;// 86400000
- // Inner class
- static class BleachNotification
- {
- public int Id;
- public String Name;
- public String Title;
- public String Content;
- public long TriggerMillis;
- public boolean Repeat;
- public BleachNotification(int id, String name, String title, String content, long triggerMillis, boolean repeat)
- {
- Id = id;
- Name=name;
- Title = title;
- Content = content;
- TriggerMillis = repeat?GetNextRepeatTime(triggerMillis):triggerMillis;
- Repeat = repeat;
- }
- private long GetNextRepeatTime(long time)
- {
- long now = System.currentTimeMillis();
- while(time<now)
- time+=RepeatInterval;
- return time;
- }
- }
- @Override
- public void onReceive(Context context, Intent intent)
- {
- String action = intent.getAction();
- Log.d("Unity", "Bleach: onReceive......................" + action);
- if (action!=null && action.equals("android.intent.action.BOOT_COMPLETED"))
- {
- for (BleachNotification bn : LoadAllNotification())
- Register(bn, false);
- }
- else
- {
- if (!intent.getBooleanExtra("repeat", true))
- {
- int id = intent.getIntExtra("id", -1);
- if (id != -1)
- DisableNotification(context, id);
- }
- NotificationManager nm=(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
- ApplicationInfo applicationInfo=null;
- try
- {
- final PackageManager pm=context.getPackageManager();
- applicationInfo = pm.getApplicationInfo(context.getPackageName(),PackageManager.GET_META_DATA);
- }
- catch (NameNotFoundException e)
- {
- Log.d("Unity","Bleach: onReceive failed, reason: get applicationInfo failed.");
- }
- Notification notification=new Notification(applicationInfo.icon,intent.getStringExtra("name"),System.currentTimeMillis());
- Intent notificationIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
- notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
- PendingIntent pi = PendingIntent.getActivity(context, 0, notificationIntent, 0);
- notification.setLatestEventInfo(context, intent.getStringExtra("title"), intent.getStringExtra("content"), pi);
- // Notify
- nm.notify(intent.getIntExtra("id",0),notification);
- Log.d("Unity","Bleach: notify succeed!");
- }
- }
- public static void Register(int id, String name, String title, String content, int secondsFromNow, boolean repeat)
- {
- Calendar calendar=Calendar.getInstance();
- calendar.setTimeInMillis(System.currentTimeMillis());
- calendar.add(Calendar.SECOND, secondsFromNow);
- long time=calendar.getTimeInMillis();
- Register(new BleachNotification(id,name,title,content,time,repeat),true);
- }
- private static void Register(BleachNotification bn,boolean isSave)
- {
- Activity activity =UnityPlayer.currentActivity;
- Intent intent =new Intent(activity, AlarmReceiver.class);
- intent.putExtra("name", bn.Name);
- intent.putExtra("title", bn.Title);
- intent.putExtra("content", bn.Content);
- intent.putExtra("id", bn.Id);
- intent.putExtra("repeat",bn.Repeat);
- PendingIntent pi=PendingIntent.getBroadcast(activity, bn.Id, intent, PendingIntent.FLAG_CANCEL_CURRENT);
- // Schedule the alarm!
- AlarmManager am = (AlarmManager)activity.getSystemService(Context.ALARM_SERVICE);
- if(bn.Repeat)
- am.setRepeating(AlarmManager.RTC_WAKEUP, bn.TriggerMillis, RepeatInterval, pi);
- else
- am.set(AlarmManager.RTC_WAKEUP,bn.TriggerMillis, pi);
- if(isSave)
- SaveNotification(bn);
- Log.d("Unity", "Bleach: Start Alarm...,id: "+bn.Id+
- " name: "+bn.Name+
- " title: "+bn.Title+
- " content: "+bn.Content+
- " triggerMillis: "+bn.TriggerMillis+
- " currentTime:"+System.currentTimeMillis()+
- " repeat: "+bn.Repeat);
- }
- public static void Unregister(int id)
- {
- Activity activity = UnityPlayer.currentActivity;
- Intent intent = new Intent(activity, AlarmReceiver.class);
- PendingIntent pi = PendingIntent.getBroadcast(activity, id, intent, PendingIntent.FLAG_CANCEL_CURRENT);
- AlarmManager am = (AlarmManager)activity.getSystemService(Context.ALARM_SERVICE);
- am.cancel(pi);
- NotificationManager mNM = (NotificationManager)activity.getSystemService(Context.NOTIFICATION_SERVICE);
- mNM.cancel(id);
- DisableNotification(activity, id);
- Log.d("Unity","Bleach: Cancel, id: "+id);
- }
- private static void DisableNotification(Context context,int id)
- {
- SharedPreferences sp = context.getSharedPreferences("Notification", Context.MODE_APPEND);
- Editor edit = sp.edit();
- String sid = String.valueOf(id);
- edit.putInt(sid, -1);
- edit.commit();
- }
- private static void SaveNotification(BleachNotification notification)
- {
- SharedPreferences sp = UnityPlayer.currentActivity.getSharedPreferences("Notification", Context.MODE_APPEND);
- Editor edit = sp.edit();
- String sid = String.valueOf(notification.Id);
- edit.putInt(sid, 1);
- edit.putString(sid + "name", notification.Name);
- edit.putString(sid + "title", notification.Title);
- edit.putString(sid + "content", notification.Content);
- edit.putLong(sid + "triggerTime", notification.TriggerMillis);
- edit.putBoolean(sid + "repeat", notification.Repeat);
- edit.commit();
- }
- private static ArrayList<BleachNotification> LoadAllNotification()
- {
- ArrayList<BleachNotification> l = new ArrayList<BleachNotification>();
- SharedPreferences sp = UnityPlayer.currentActivity.getSharedPreferences("Notification", Context.MODE_APPEND);
- int index = 0;
- while (index < NotificationCount)
- {
- String id = String.valueOf(index);
- if (sp.getInt(id, -1) != -1)
- {
- BleachNotification bn=new BleachNotification(
- index,
- sp.getString(id + "name", ""),
- sp.getString(id + "title", ""),
- sp.getString(id + "content",""),
- sp.getLong(id + "triggerTime", 0),
- sp.getBoolean(id + "repeat", false)
- );
- l.add(bn);
- }
- index++;
- }
- return l;
- }
- }
AlarmReceiver
manifest配置为:
- <!-- Add by tj[-->
- <receiver android:name="com.example.localpush.AlarmReceiver">
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
- </intent-filter>
- </receiver>
- <activity
- android:name="com.unity3d.player.UnityPlayerProxyActivity"
- android:label="@string/app_name"
- android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" >
- </activity>
- <activity
- android:name="com.unity3d.player.UnityPlayerActivity"
- android:label="@string/app_name"
- android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" >
- </activity>
- <activity
- android:name="com.unity3d.player.UnityPlayerNativeActivity"
- android:label="@string/app_name"
- android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" >
- <meta-data android:name="android.app.lib_name" android:value="unity" />
- <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />
- </activity>
- <!-- ] -->
Manifest
3. ios 直接调用 unity3d 的 api,实现如下:
- #if UNITY_IPHONE
- using System;
- using UnityEngine;
- public class IOSNotification : INotification
- {
- static IOSNotification()
- {
- Clear();
- NotificationServices.RegisterForLocalNotificationTypes(LocalNotificationType.Alert);
- }
- public void Register(int id, string name, string title, string content, DateTime triggerTime, bool repeat)
- {
- var iosNotification = new LocalNotification()
- {
- alertBody = content,
- hasAction = false,
- applicationIconBadgeNumber = ,
- fireDate = triggerTime,
- soundName = LocalNotification.defaultSoundName,
- };
- if (repeat)
- {
- iosNotification.repeatCalendar = CalendarIdentifier.ChineseCalendar;
- iosNotification.repeatInterval = CalendarUnit.Day;
- }
- NotificationServices.ScheduleLocalNotification(iosNotification);
- }
- public void Unregister(int id)
- {
- }
- public void ClearAll()
- {
- Clear();
- }
- static void Clear()
- {
- var ln = new LocalNotification()
- {
- applicationIconBadgeNumber = -
- };
- NotificationServices.PresentLocalNotificationNow(ln);
- NotificationServices.CancelAllLocalNotifications();
- NotificationServices.ClearLocalNotifications();
- }
- #region INotification
- public void Dispose()
- {
- }
- #endregion
- }
- #endif
IOSNotification
4. 最后是一个与上层交互的接口:
- using System;
- using UnityEngine;
- // 本地推送的类型,注意:id不能重复
- public enum NotificationType
- {
- SevenDaysNoLogin = , // 7日登陆
- SpecialTrain = , // 紧急特训
- SpaTime = , // 温泉
- LoginNextDay = , // 次日登陆
- PuYuanShopRefresh = , // 浦原商店刷新
- WorldBossOpen = , // 世界boss开启
- }
- public class NotificationManager : IDisposable
- {
- INotification m_notification;
- #region Singleton
- static NotificationManager s_instance;
- public static NotificationManager Instance
- {
- get
- {
- if (s_instance == null)
- s_instance = new NotificationManager();
- return s_instance;
- }
- }
- #endregion
- #region DefaultNotification
- class DefaultNotification : INotification
- {
- public void Register(int id, string name, string title, string content, DateTime triggerTime, bool repeat)
- {
- }
- public void Unregister(int id)
- {
- }
- public void ClearAll()
- {
- }
- public void Dispose()
- {
- }
- }
- #endregion
- private NotificationManager()
- {
- m_notification = CreateObj();
- }
- INotification CreateObj()
- {
- INotification obj;
- #if UNITY_EDITOR
- obj = new DefaultNotification();
- #elif UNITY_ANDROID
- obj = new AndroidNotification();
- #elif UNITY_IPHONE
- obj = new IOSNotification();
- #else
- obj = new DefaultNotification();
- Debugger.LogWarning("Local push not support this platform");
- #endif
- return obj;
- }
- public void Register(int id, string content, DateTime triggerTime, bool repeat)
- {
- if (string.IsNullOrEmpty(content))
- throw new ArgumentException("content");
- string title = MLocalization.Get(""); // 游戏名
- if (string.IsNullOrEmpty(title))
- throw new ArgumentException("title");
- m_notification.Register(id, content, title, content, triggerTime, repeat);
- Debug.Log(string.Format("local push, id: {0}, title: {1}, content: {2}, Time: {3} repeat: {4}", id, title, content, triggerTime, repeat));
- }
- public void Register(NotificationType type, string content, DateTime triggerTime, bool repeat)
- {
- Register((int)type, content, triggerTime, repeat);
- }
- public void Unregister(int id)
- {
- m_notification.Unregister(id);
- }
- public void Unregister(NotificationType type)
- {
- Unregister((int)type);
- }
- public void ClearAll()
- {
- m_notification.ClearAll();
- }
- /// <summary>
- /// 登陆完成后更新本地推送
- /// </summary>
- public void UpdateWhenLoginComplete()
- {
- UpdateSevenDaysNoLogin();
- //UpdateLoginNextDay();
- UpdatePuYuanShopRefresh();
- UpdateWorldBossOpen();
- }
- #region Special notification
- // 七天未登陆
- void UpdateSevenDaysNoLogin()
- {
- string content = MLocalization.Get("");
- var time = PlayerInfo.Instance().GetServerNow().AddDays();
- Unregister(NotificationType.SevenDaysNoLogin);
- Register(NotificationType.SevenDaysNoLogin, content, time, false);
- }
- // 紧急特训
- public void RegisterSpecialTrain(TrainingSpecially tr)
- {
- string content = MLocalization.Get("");
- Register(NotificationType.SpecialTrain, content, tr.begin_time, true);
- }
- // 温泉
- public void UpdateSpaTime()
- {
- string content = null;
- // spaTime just notify once
- //for (int i = 0; i < ActivityInfoValue.Instance().spaStartTimeList.Count; i++)
- //{
- int notiId = (int)NotificationType.SpaTime + ;
- Unregister(notiId);
- if (SystemSettingModel.Instance.NotifyHotSpring) // 系统设置
- {
- ulong spaStartTime = ActivityInfoValue.Instance().spaStartTimeList[];
- DateTime dateTimeStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(, , ));
- DateTime dateTimeTrigger = dateTimeStart.AddSeconds(spaStartTime).ToLocalTime();
- if (content == null)
- content = MLocalization.Get("");
- Register(notiId, content, dateTimeTrigger, true);
- }
- //}
- }
- public void ClearSpaTime()
- {
- if (ActivityInfoValue.Instance().spaStartTimeList == null)
- return;
- for (int i = ; i < ActivityInfoValue.Instance().spaStartTimeList.Count; i++)
- {
- int notiId = (int)NotificationType.SpaTime + i;
- Unregister(notiId);
- }
- }
- /*
- * 当玩家首次打开客户端进入游戏时,设置一条推送,在第二天的20点进行推送
- * 当玩家第二天20点之前,登录过游戏,则取消此条推送。
- * 推送文字为“你今天还没有登录死神哦,登录即可入手斩月。“(本文字为语言包文字)
- */
- void UpdateLoginNextDay()
- {
- string prefKey = string.Format("LocalPush.{0}.{1}", PlayerInfo.Instance().roleID, NotificationType.LoginNextDay);
- int prefValue = PlayerPrefs.GetInt(prefKey);
- Unregister(NotificationType.LoginNextDay);
- if (prefValue <= )
- {
- DateTime serverNow = PlayerInfo.Instance().GetServerNow();
- string timeString = GameOption.Instance().NotifyBladeTime;
- DateTime time = DateTime.Parse(timeString);
- DateTime triggerTime = new DateTime(serverNow.Year, serverNow.Month, serverNow.Day, time.Hour, time.Minute, ).AddDays();
- string content = MLocalization.Get("");
- Register(NotificationType.LoginNextDay, content, triggerTime, false);
- PlayerPrefs.SetInt(prefKey, );
- }
- }
- // 浦原商店刷新
- public void UpdatePuYuanShopRefresh()
- {
- Unregister(NotificationType.PuYuanShopRefresh);
- if (SystemSettingModel.Instance.NotifyShopRefresh)
- {
- DateTime time = DateTime.Parse(GameOption.Instance().refreshShopResetTime[]); // 只需要每天9点推送
- DateTime serverNow = PlayerInfo.Instance().GetServerNow();
- DateTime triggerTime = new DateTime(serverNow.Year, serverNow.Month, serverNow.Day, time.Hour, time.Minute, );
- string content = MLocalization.Get("");
- Register(NotificationType.PuYuanShopRefresh, content, triggerTime, true);
- }
- }
- // 世界 boss 开启
- public void UpdateWorldBossOpen()
- {
- Unregister(NotificationType.WorldBossOpen);
- bool isOpen = PlayerInfo.Instance().openedSystemID.Contains((uint)SystemEnum.WorldBoss);
- if (isOpen && SystemSettingModel.Instance.NotifyWorldBossOpen)
- {
- string content = MLocalization.Get("");
- DateTime serverNow = PlayerInfo.Instance().GetServerNow();
- string timeString = GameOption.Instance().bossYammyNotifyTime;
- DateTime time = DateTime.Parse(timeString);
- DateTime triggerTime = new DateTime(serverNow.Year, serverNow.Month, serverNow.Day, time.Hour, time.Minute, );
- Register(NotificationType.WorldBossOpen, content, triggerTime, true);
- }
- }
- #endregion
- public void Dispose()
- {
- m_notification.Dispose();
- }
- }
NotificationManager
转载请注明出处:http://www.cnblogs.com/jietian331/p/5025561.html
unity3d 之本地推送的更多相关文章
- iOS-推送,证书申请,本地推送
介绍一点点背景资料 众所周知,使用推送通知是一个很棒的.给应用添加实时消息通知的方式.这样做的结局是,开发者和用户之间,彼此永远保持着一种令人愉悦的亲密关系. 然而不幸的是,iOS的推送通知并非那么容 ...
- iOS 本地推送通知
1.什么是本地推送通知 不需要联网的情况下,应用程序经由系统发出的通知 2.本地推送的使用场景 定时提醒,如玩游戏.记账.闹钟.备忘录等 3.实现本地推送通知的步骤 创建本地推送通知的对象UILoca ...
- IOS中程序如何进行推送消息(本地推送,远程推送)
[1]-------------什么是推送消息? 我就以一张图解释------------ [2]-----------IOS程序中如何进行本地推送?----------- 2.1,先征求用户同意 1 ...
- IOS 本地推送 IOS10.0以上 static的作用 const的作用
//需要在AppDelegate里面启动APP的函数 加上 UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNot ...
- 本地推送UILocalNotification
//本地推送---无需网络,由本地发起 UILocalNotification *localNotification = [[UILocalNotification alloc]init]; //设置 ...
- iOS本地推送与远程推送
原文在此 分为本地推送和远程推送2种.可以在应用没有打开甚至手机锁屏情况下给用户以提示.它们都需要注册,注册后系统会弹出提示框(如下图)提示用户是否同意,如果同意则正常使用:如果用户不同意则下次打开程 ...
- IOS之推送通知(本地推送和远程推送)
推送通知和NSNotification是有区别的: NSNotification:是看不到的 推送通知:是可以看到的 IOS中提供了两种推送通知 本地推送通知:(Local Notification) ...
- Swift - 推送之本地推送(UILocalNotification)添加Button的点击事件
上一篇讲到的本地推送是普通的消息推送,本篇要讲一下带按钮动作的推送消息 import UIKit @UIApplicationMain class AppDelegate: UIResponder, ...
- Swift - 推送之本地推送(UILocalNotification)
// 本地推送通知是通过实例化UILocalNotification实现的.要实现本地化推送可以在AppDelegate.swift中添加代码实现,本事例是一个当App进入后台时推送一条消息给用户. ...
随机推荐
- SpringMVC redirect乱码问题
转:http://blog.csdn.net/xubo_zhang/article/details/8239725 spring redirect 用spring redirect中文会乱码:如下示例 ...
- awk 用法小结
简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再 ...
- ignite客户端找不到服务端的时候如何设置退出
ignite启动客户端时需要有服务端支持: Ignition.setClientMode(true); Ignition.start("ignite.xml"); 这里有个问题,当 ...
- hiho1246(数学求模)
input 1<=n<=2000 a1 a2 ... an 1<=ai<=5*10e7 output n行,第i行指切成i段,每段和的最大公约数的最大值 做法:环形数组切成n段 ...
- PostConstruct注解
应用场景:当你需要往Bean里注入一个其父类中定义的属性,而你又无法复写父类的属性或属性的setter方法时 public class UserDaoImpl extends HibernateDao ...
- libmysql.dll 找不到
在用C#开发的时候,需要连接MySQL ,系统提示 libmysql.dll 找不到模块. 我们可以找到 MySQL安装文件夹下的 C:\Program Files\MySQL\MySQL Ser ...
- 内存管理 & 内存优化技巧 浅析
内存管理 浅析 下列行为都会增加一个app的内存占用: 1.创建一个OC对象: 2.定义一个变量: 3.调用一个函数或者方法. 如果app占用内存过大,系统可能会强制关闭app,造成闪退现象,影响用户 ...
- ActiveMQ的配置与使用
1.什么是ActiveMQ MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过写和检索出入列队的针对应用程序的数据(消息)来通信,而无需专用连接来 ...
- 转:使用WebDriver过程中遇到的那些问题
在做web项目的自动化端到端测试时主要使用的是Selenium WebDriver来驱动浏览器.Selenium WebDriver的优点是支持的语言多,支持的浏览器多.主流的浏览器Chrome.Fi ...
- circularprogressbar/smoothprogressbar开源视图使用学习
github地址:https://github.com/castorflex/SmoothProgressBar 多彩圆形进度条和多彩水平进度条 colors.xml 定义变化的颜色内容,用gplus ...