cocos2dx 本地推送通知的实现
用coocs2dx引擎开发单机,或者若联网游戏,加入推送通知是很有必要的。现在把本人在项目中做的推送通知整理一下供大家参考,抛砖引玉,我是调用的android 和 ios 平台自己的推送。
首先是一个管理者:
#ifndef __CCNOTIFICATION_MANAGER_H__
#define __CCNOTIFICATION_MANAGER_H__
#define NM CCNotificationManager::getNotificationManager()
#include "GlobalHead.h"
class CCNotificationManager
{
public:
static CCNotificationManager* getNotificationManager();
void notification(const char * message,long delay,int repeats,const char * key);
private:
CCNotificationManager();
private:
staticCCNotificationManager* m_pNotifiMgr;
};
#include "CCNotificationManager.h"
#include "CCTimeHelper.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
#include "CCNotificationHelper.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "CCNotificationAndroid.h"
#endif
CCNotificationManager* CCNotificationManager::m_pNotifiMgr = NULL;
CCNotificationManager::CCNotificationManager()
{
}
CCNotificationManager* CCNotificationManager::getNotificationManager()
{
if (NULL == m_pNotifiMgr)
{
m_pNotifiMgr = newCCNotificationManager();
returnm_pNotifiMgr;
}
returnm_pNotifiMgr;
}
void CCNotificationManager::notification(const char * message,long delay,int repeats,const char * key)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
// CNH->pushMessage(message ,delay ,repeats,key );
CNH->pushMessage(message ,delay ,0,key );
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
java_push(message,delay + GTH->getCurrentTime(),repeats);
#endif
}
#endif
ios 下 的实现。
#ifndef __CCNOTIFICATION_HELPER_H__
#define __CCNOTIFICATION_HELPER_H__
#include <stdio.h>
#include <time.h>
#include "GlobalHead.h"
class CCNotificationHelper
{
public:
static CCNotificationHelper* sharedInstance();
void pushMessage(const char * message,long delay,int repeats,const char * key);
void removeNotification();
private:
CCNotificationHelper();
private:
static CCNotificationHelper* m_pNotification;
bool m_accept;
};
#define CNH CCNotificationHelper::sharedInstance()
#endif /* defined(__CCNOTIFICATION_HELPER_H__) */
#include "CCNotificationHelper.h"
CCNotificationHelper* CCNotificationHelper::m_pNotification = NULL;
CCNotificationHelper* CCNotificationHelper::sharedInstance()
{
if (!m_pNotification)
{
m_pNotification = newCCNotificationHelper();
returnm_pNotification;
}
returnm_pNotification;
}
void CCNotificationHelper::pushMessage(const char * message,long delay,int repeats,const char * key)
{
// repeats 0:不重复 1:/DAY 2:/HOUR 3:/MINUTE 4:SECOND
NSString * castStr = [[NSStringalloc] initWithUTF8String:message];
NSString * keyStr = [[NSStringalloc] initWithUTF8String:key];
//1、增加一个本地推送
NSDate *date = [NSDatedateWithTimeIntervalSinceNow:delay];
//创建一个本地推送
UILocalNotification *noti = [[[UILocalNotificationalloc] init] autorelease];
if (noti) {
//设置推送时间
noti.fireDate = date;
//设置时区
noti.timeZone = [NSTimeZonedefaultTimeZone];
//设置重复间隔
if(repeats == 1)
{
noti.repeatInterval = kCFCalendarUnitDay;
}else if (repeats == 2)
{
noti.repeatInterval = kCFCalendarUnitHour;
}else if (repeats == 3)
{
noti.repeatInterval = kCFCalendarUnitMinute;
}else if (repeats == 4)
{
noti.repeatInterval = kCFCalendarUnitSecond;
}else
{
noti.repeatInterval = 0;
}
//推送声音
noti.soundName = UILocalNotificationDefaultSoundName;
//内容
noti.alertBody = castStr;
// //显示在icon上的红色圈中的数子
noti.applicationIconBadgeNumber = 0;
//设置userinfo 方便在之后需要撤销的时候使用
NSDictionary *infoDic = [NSDictionarydictionaryWithObject:keyStr forKey:keyStr];
noti.userInfo = infoDic;
//添加推送到uiapplication
UIApplication *app = [UIApplicationsharedApplication];
[app scheduleLocalNotification:noti];
}
[castStr release];
[keyStr release];
}
void CCNotificationHelper::removeNotification()
{
[[UIApplicationsharedApplication] cancelAllLocalNotifications];
}
CCNotificationHelper::CCNotificationHelper()
{
}
android下的实现
#ifndef __CCNOTIFICATION_ANDROID_H__
#define __CCNOTIFICATION_ANDROID_H__
#include "GlobalHead.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
extern"C"
{
extern void java_push(string message,long mark,int repeats);
extern void java_removePush();
}
#endif
#endif
#include "CCNotificationAndroid.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "jni/JniHelper.h"
#include <android/log.h>
#include <jni.h>
extern"C"
{
void java_push(string message,long mark,int repeats)
{
JniMethodInfo t;
//LI
if (JniHelper::getStaticMethodInfo(t,"com/ea/product/alpaca/alpaca","pushMessage","(Ljava/lang/String;JI)V"))
{
jstring messageStr = t.env->NewStringUTF(message.c_str());
t.env->CallStaticVoidMethod(t.classID,t.methodID,messageStr,mark,repeats);
t.env->DeleteLocalRef(messageStr);
}
}
void java_removePush()
{
JniMethodInfo minfo;
bool isHave = JniHelper::getStaticMethodInfo(minfo,"com/ea/product/alpaca/alpaca","removeNotification", "()V");
if (!isHave)
{
CCLOG("jni:此函数不存在");
}
else
{
minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID);
}
}
}
#endif
然后切换到pro.android
public class alpaca extends Cocos2dxActivity {
public finalstaticint convert = 1000;
public finalstatic String SER_KEY = "com.ea.product.alpaca.message";
publicstatic alpaca malpacaObj;
protected void onCreate(Bundle savedInstanceState) {
Log.e("com.ea.product.alpaca", "onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
malpacaObj = this;
}
public Cocos2dxGLSurfaceView onCreateView() {
Log.e("com.ea.product.alpaca", "onCreateView");
Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
// alpaca should create stencil buffer
glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
return glSurfaceView;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
//Serializeable传递对象的方法
public void SerializeMethod(NotificationMessage message) {
Intent intent = new Intent();
intent.setClass(alpaca.this, CCNotifitionService.class);
Bundle mBundle = new Bundle();
mBundle.putSerializable(SER_KEY, message);
intent.putExtras(mBundle);
alpaca.this.startService(intent);
System.out.println("Push notify message.");
}
public static void pushMessage(String message,long mark,int repeats) {
System.out.println("alpaca.passFromJni()"+mark);
NotificationMessage nmObj = new NotificationMessage();
nmObj.setMessage(message);
nmObj.setMark(mark * convert);
nmObj.setId(repeats);
malpacaObj.SerializeMethod(nmObj);
}
public void onStop() {
super.onStop();
}
public void onDestroy() {
super.onDestroy();
}
public alpaca() {
}
static {
System.loadLibrary("alpaca");
}
}
这个是一个实体model
package com.ea.product.alpaca;
import java.io.Serializable;
public class NotificationMessage implements Serializable{
private static final long serialVersionUID = -7060210544600464481L;
private String message;
privatelong mark;
privateint id;
public String getMessage() {
returnmessage;
}
public void setMessage(String message) {
this.message = message;
}
public long getMark() {
returnmark;
}
public void setMark(long mark) {
this.mark = mark;
}
public int getId() {
returnid;
}
public void setId(int id) {
this.id = id;
}
public NotificationMessage(String message, long mark, int id) {
super();
this.message = message;
this.mark = mark;
this.id = id;
}
public NotificationMessage() {
}
}
最后在service中做逻辑处理(启动一个定时器到时间就推送)
package com.ea.product.alpaca;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import com.ea.product.alpaca.alpaca;
import android.app.NotificationManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
public class CCNotifitionService extends Service {
static List<NotificationMessage> mMessageList = new ArrayList<NotificationMessage>();
String mmessage = "" ;
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public CCNotifitionService(){
System.out.println("CCNotifitionService.CCNotifitionService()");
}
@Override
public void onCreate()
{
System.out.println("onCreate()"+mMessageList.size());
super.onCreate();
Timer timer = new Timer(true);
timer.schedule(
new java.util.TimerTask()
{
public void run() {
if(checkPushStatue())
{
showNotification();
}
}
}, 0, 1*1000);
}
@Override
public void onStart(Intent intent, int startId)
{
if((intent!=null) )
{
NotificationMessage message = (NotificationMessage)intent.getSerializableExtra(alpaca.SER_KEY);
mMessageList.add(message);
}
}
@Override
public void onDestroy() {
super.onDestroy();
}
public CCNotifitionService(Context context){
}
public boolean checkPushStatue(){
long currentTime = System.currentTimeMillis();
if(mMessageList.size()>0)
{
int listSize = mMessageList.size();
for(int i = 0 ;i<listSize;i++){
if(mMessageList.get(i).getMark() < currentTime)
{
mmessage = mMessageList.get(i).getMessage();
mMessageList.remove(i);
return true;
}
else
{
return false;
}
}
}
else
{
return false;
}
return false;
}
public void showNotification()
{
Notification notification = new Notification(R.drawable.icon, mmessage, System.currentTimeMillis());
notification.defaults = Notification.DEFAULT_SOUND;
Intent it = new Intent(Intent.ACTION_MAIN);
it.setClassName(this,"com.ea.product.alpaca.alpaca");
it.addCategory(Intent.CATEGORY_LAUNCHER);
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
PendingIntent pintent = PendingIntent.getActivity(CCNotifitionService.this, 0,it,0);
notification.setLatestEventInfo(CCNotifitionService.this,"",mmessage,pintent);
String service = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager =(NotificationManager)getSystemService(service);
mNotificationManager.notify(R.string.app_name, notification);
}
public class PushThread implements Runnable {
public void run() {
System.out.println("CCNotifitionService.PushThread.run()"+mMessageList.size());
while(true)
{
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(checkPushStatue())
{
showNotification();
}
}
}
}
}
最后千万不能忘了在配置文件中加入这个service的属性
<serviceandroid:enabled="true"android:name=".CCNotifitionService"
android:process=":message"
/>
这样就可以在用户退出后,开启一个新的进程来处理逻辑(判断满足条件推送)