正文
cocos2d-js 安卓自定义本地通知功能
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
安卓新手,笔记有理解不当的地方望指出,经过几天折腾终于可以实现类似ios的本地通知功能(ios就几行代码),可能有第三方sdk可以方便实现,暂时没去找
思路:
1。 startService 和bindService 同时存在
startService 新开进程 注意AndroidMenifest.xml中添加process
<service android:name="org.cocos2dx.javascript.LocalPush"
android:process=":remote">
</service>
这里的remote可以自定义任意名称,前面冒号代表与原Activity不同的独立进程
因为两个进程互相独立,需要通讯,使用AIDL方式
Activity.java
@Override protected void onStart() { Log.i(TAG,"onStart"); super.onStart(); Bundle args = new Bundle(); args.putString("param", "oper1"); Intent intent = new Intent(AppActivity.this, LocalPush.class); intent.putExtras(args); startService(intent); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { Log.i(TAG,"onStop"); super.onStop(); unbindService(mConnection); } static forService mService; private forActivity mCallback = new forActivity.Stub() {
@SuppressLint("ShowToast") public void performAction() throws RemoteException {
Toast.makeText(AppActivity.this, "this toast is called from service", ).show();
}
};
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
Log.i(TAG,"onServiceConnected");
mService = forService.Stub.asInterface(service);
try {
mService.registerTestCall(mCallback);
}
catch (RemoteException e) { }
}
public void onServiceDisconnected(ComponentName className) {
Log.i(TAG,"disconnect service");
mService = null;
}
};
LocalPush.java 继承自 Service
public class LocalPush extends Service {
private forActivity callback; // public LocalPush() {
// super("LocalPush");
// }
//
// @Override
// protected void onHandleIntent(Intent intent) {
// String action = intent.getExtras().getString("param");
// Log.i(TAG, "onHandleIntent");
// notifyArr = new Vector<CustomNotify>();
// messageNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// // IntentService会使用单独的线程来执行该方法的代码
// while (isRunning) {
// Log.i(TAG, "Service tick--->1");
// try {
// Log.i(TAG, "Service tick--->2");
// //休息1秒
// Thread.sleep(1000);
// Log.i(TAG, "Service tick--->3");
// sendNotifies();
// Log.i(TAG, "Service tick--->4");
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// }
// private final IBinder binder = new LocalBinder();
// public class LocalBinder extends Binder {
// LocalPush getService() {
// return LocalPush.this;
// }
// } private final forService.Stub mBinder = new forService.Stub() {
@Override
public void invokCallBack(int _alertTime, String _key, String _alertBody, String _title, String _content, boolean _isEndClean) throws RemoteException {
//callback.performAction();
registerLocalNotification(_alertTime, _key, _alertBody, _title, _content, _isEndClean);
}
@Override
public void registerTestCall(forActivity cb) throws RemoteException {
callback = cb;
}
}; //当使用startService()方法启动Service时
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "IBinder onBin");
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG,"service on unbind");
return super.onUnbind(intent);
}
public void onRebind(Intent intent) {
Log.i(TAG, "service on rebind");
super.onRebind(intent);
} //Service时被调用
@SuppressWarnings("deprecation")
@Override
public void onCreate() {
Log.i(TAG, "Service onCreate--->1");
super.onCreate();
//startForeground(-1213, new Notification());
Notification notification = new Notification();
notification.icon = R.drawable.icon; //通知图片 Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setClass(LocalPush.this, AppActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(LocalPush.this, , intent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(LocalPush.this, "Slots", "Click return to Slots!", pendingIntent);
startForeground(0x1982, notification); // notification ID: 0x1982, you can name it as you will. messageThread = new MessageThread(); messageThread.start(); }
class MessageThread extends Thread { //运行状态 public boolean isRunning = true; @Override public void run() { while(isRunning) { synchronized(this) { try { //休息1秒 Thread.sleep(); sendNotifies(); //这里判断是否需要发出通知 } catch (Exception e) { e.printStackTrace(); Thread.currentThread().interrupt(); } } } } } @Override
//当调用者使用startService()方法启动Service时,该方法被调用
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service onStart--->1:"+ flags+" stargId:" + startId);
return super.onStartCommand(intent, flags, startId);
}
@Override
//当Service不在使用时调用
public void onDestroy() {
Log.i(TAG, "Service onDestroy--->");
super.onDestroy();
stopForeground(true);
}
}
forActivity.aidl
package org.cocos2dx.javascript;
interface forActivity {
void performAction();
}
forService.aidl
package org.cocos2dx.javascript;
import org.cocos2dx.javascript.forActivity;
interface forService {
void registerTestCall(forActivity cb);
void invokCallBack(int _alertTime, String _key, String _alertBody, String _title, String _content, boolean _isEndClean);
}
2 通知
cocos3 以上支持js反射到java,Activity中创建对应Static 方法 ,
大概这样
public static void registerLocalNotification(int _alertTime, String _key, String _alertBody, String _title, String _content, boolean _isEndClean) {
Log.i(TAG, "registerLocalNotification1 "+_alertTime+" "+_key+" "+_alertBody+" "+_title+" "+_content+" "+_isEndClean);
//mService.registerLocalNotification(_alertTime, _key, _alertBody, _title, _content, _isEndClean);
Log.i(TAG, "registerLocalNotification2 "+_alertTime+" "+_key+" "+_alertBody+" "+_title+" "+_content+" "+_isEndClean);
try {
mService.invokCallBack(_alertTime, _key, _alertBody, _title, _content, _isEndClean);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
service端相应方法,思路:开启新线程实时 比对通知世间簇和当前世间簇,如果结果为 小于等于 则发出通知
//注册通知
public void registerLocalNotification(int _alertTime, String _key, String _alertBody, String _title, String _content, boolean _isEndClean) {
...
}
发通知大概这样
private Intent messageIntent = null;
private PendingIntent messagePendingIntent = null;
//通知栏消息
private int messageNotificationID = 1000;
private Notification messageNotification = null;
private NotificationManager messageNotificationManager;
@SuppressWarnings("deprecation")
public void commitNotify () {
finishFlag = true;
//初始化
messageNotification = new Notification();
messageNotification.icon = R.drawable.icon; //通知图片
messageNotification.defaults = Notification.DEFAULT_SOUND;
//点击查看 messageIntent = new Intent(Intent.ACTION_MAIN);
messageIntent.addCategory(Intent.CATEGORY_LAUNCHER);
messageIntent.setClass(LocalPush.this, AppActivity.class);
messageIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); // //Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED //messageIntent = new Intent(LocalPush.this, AppActivity.class);
messagePendingIntent = PendingIntent.getActivity(LocalPush.this, , messageIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//设置消息内容和标题
messageNotification.setLatestEventInfo(LocalPush.this, title, content, messagePendingIntent);
//messageNotification.when = System.currentTimeMillis();
messageNotification.number = ;
//messageNotification.flags |= Notification.FLAG_AUTO_CANCEL; // FLAG_AUTO_CANCEL表明当通知被用户点击时,通知将被清除。
// 通过通知管理器来发起通知。如果id不同,则每click,在statu那里增加一个提示 //避免覆盖消息,采取ID自增
messageNotificationManager.notify(++ messageNotificationID, messageNotification);
}