安卓新手,笔记有理解不当的地方望指出,经过几天折腾终于可以实现类似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", 1).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, 0, 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(1000); 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, 0, messageIntent, PendingIntent.FLAG_UPDATE_CURRENT); //设置消息内容和标题 messageNotification.setLatestEventInfo(LocalPush.this, title, content, messagePendingIntent); //messageNotification.when = System.currentTimeMillis(); messageNotification.number = 1; //messageNotification.flags |= Notification.FLAG_AUTO_CANCEL; // FLAG_AUTO_CANCEL表明当通知被用户点击时,通知将被清除。 // 通过通知管理器来发起通知。如果id不同,则每click,在statu那里增加一个提示 //避免覆盖消息,采取ID自增 messageNotificationManager.notify(++ messageNotificationID, messageNotification); }