参考: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 之本地推送的更多相关文章

  1. iOS-推送,证书申请,本地推送

    介绍一点点背景资料 众所周知,使用推送通知是一个很棒的.给应用添加实时消息通知的方式.这样做的结局是,开发者和用户之间,彼此永远保持着一种令人愉悦的亲密关系. 然而不幸的是,iOS的推送通知并非那么容 ...

  2. iOS 本地推送通知

    1.什么是本地推送通知 不需要联网的情况下,应用程序经由系统发出的通知 2.本地推送的使用场景 定时提醒,如玩游戏.记账.闹钟.备忘录等 3.实现本地推送通知的步骤 创建本地推送通知的对象UILoca ...

  3. IOS中程序如何进行推送消息(本地推送,远程推送)

    [1]-------------什么是推送消息? 我就以一张图解释------------ [2]-----------IOS程序中如何进行本地推送?----------- 2.1,先征求用户同意 1 ...

  4. IOS 本地推送 IOS10.0以上 static的作用 const的作用

    //需要在AppDelegate里面启动APP的函数 加上 UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNot ...

  5. 本地推送UILocalNotification

    //本地推送---无需网络,由本地发起 UILocalNotification *localNotification = [[UILocalNotification alloc]init]; //设置 ...

  6. iOS本地推送与远程推送

    原文在此 分为本地推送和远程推送2种.可以在应用没有打开甚至手机锁屏情况下给用户以提示.它们都需要注册,注册后系统会弹出提示框(如下图)提示用户是否同意,如果同意则正常使用:如果用户不同意则下次打开程 ...

  7. IOS之推送通知(本地推送和远程推送)

    推送通知和NSNotification是有区别的: NSNotification:是看不到的 推送通知:是可以看到的 IOS中提供了两种推送通知 本地推送通知:(Local Notification) ...

  8. Swift - 推送之本地推送(UILocalNotification)添加Button的点击事件

    上一篇讲到的本地推送是普通的消息推送,本篇要讲一下带按钮动作的推送消息 import UIKit @UIApplicationMain class AppDelegate: UIResponder, ...

  9. Swift - 推送之本地推送(UILocalNotification)

    // 本地推送通知是通过实例化UILocalNotification实现的.要实现本地化推送可以在AppDelegate.swift中添加代码实现,本事例是一个当App进入后台时推送一条消息给用户. ...

随机推荐

  1. mouse的各种事件

    IE测试对象为IE9,不全 mousemove(元素内部移动) 鼠标在元素内部移动时触发,只要鼠标移动,即使只是又移动了一个像素,也会触发,这就意味着短时间内会触发多次事件 支持情况: js onmo ...

  2. linux sort 用法

    sort命令是帮我们依据不同的数据类型进行排序,其语法及常用参数格式: sort [-bcfMnrtk][源文件][-o 输出文件]补充说明:sort可针对文本文件的内容,以行为单位来排序. 参 数: ...

  3. 查找List中的最大最小值

    以下实例演示了如何使用 Collections 类的 max() 和 min() 方法来获取List中最大最小值: import java.util.*; public class Main { pu ...

  4. Spotlights

    Spotlights time limit per test 1 second memory limit per test 256 megabytes input standard input out ...

  5. iOS生成一个32位的UUID

    - (NSString *)uuidString { CFUUIDRef uuid_ref = CFUUIDCreate(NULL); CFStringRef uuid_string_ref= CFU ...

  6. InnoDB的数据页结构

    页是InnoDB存储引擎管理数据库的最小磁盘单位.页类型为B-tree node的页,存放的即是表中行的实际数据了. InnoDB数据页由以下七个部分组成,如图所示: File Header(文件头) ...

  7. 使用ReTrofit做缓存(结合上拉加载和下拉刷新)

    1. noCache 不使用缓存,全部走网络 2. noStore 不使用缓存,也不存储缓存 3. onlyIfCached 只使用缓存 4. maxAge 设置最大失效时间,失效则不使用 需要服务器 ...

  8. sublime使用方法

    一.sublime菜单简介[常用功能及快捷键] [Edit菜单] 1.line行操作快捷键 ctrl+] 增加缩进 ctrl+[ 减小缩进 ctrl+shift+D 复制当前行 ctrl+shift+ ...

  9. HDU 5215 BestCoder"杯中国大学生程序设计冠军赛” 边双连通分量取出子图+二分染色判图内奇偶环

    Cycle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Sub ...

  10. 【转】CentOS安装PF_RING(虚拟机)

    1.       概述 PF_RING是Luca Deri发明的提高内核处理数据包效率,并兼顾应用程序的补丁,如Libpcap和TCPDUMP等,以及一些辅助性程序(如ntop查看并分析网络流量等). ...