运行建立多个提醒,每个提醒设置一个时间,到达指定时间后跳出提醒窗体
每个提醒有一个执行按钮,点击后保存执行记录,并且当天不再触发提醒窗体
提醒出现后如果任务还没执行,那么需要在30分钟后再次提醒
用户可以关闭全局提醒服务--指闹钟,或针对某个提醒关闭提醒服务,也可以针对某个提醒只关闭当天提醒服务
2个方案
使用的API-17
需要读写SD卡与自启动以及解锁屏幕的权限
A方案:
使用一个"前端服务"--StartFrontServer,在服务里每2分钟跑个任务,这个任务从数据库sqlite读取全部提醒,然后判断那个提醒需要激活,每次也只激活一个
被激活的提醒会更新LastNotifyTime=当前时间,并且在接下来的半个小时内不再触发(如果任务依然没有标记成[已执行]即LastActTime=当天),。
MedicineFrontService类:
1.在启动程序(EMApplication-onCreate方法中)以及收到开机广播或调整时间等时调用下启动服务,这个重载会立即安排个任务
2.runable代码流程参考下文的图片
3.runable只是一个接口不是自己安排线程,这里是关联到主线程调用
4.private Handler handler=new Handler();//不需要编写handler的消息处理代码
5.提醒窗体使用了AlarmAlertWakeLock来在有屏幕锁的情况下显示提醒窗体
public class MedicineFrontService extends Service { private static final Integer ForegroundId=1001; /* * 启动一个前端服务, 在EMApplication中启动 * 这个服务内部有个Handler来每3分钟检测一次是否有要触发的提醒 * 前端服务部容易被回收 * * (non-Javadoc) * @see android.app.Service#onCreate() */ @SuppressLint("NewApi") @Override public void onCreate() { // TODO Auto-generated method stub Log.d(TAG, "onCreate"); Notification.Builder builder = new Notification.Builder (this.getApplicationContext()); //获取一个Notification构造器 Intent nfIntent = new Intent(this, MedicineMainActivity.class); builder.setContentIntent(PendingIntent. getActivity(this, 0, nfIntent, 0)) // 设置PendingIntent .setLargeIcon(BitmapFactory.decodeResource(this.getResources(),R.drawable.ic_launcher)) // 设置下拉列表中的图标(大图标) .setContentTitle("任务提醒服务") // 设置下拉列表里的标题 .setSmallIcon(R.drawable.ic_launcher) // 设置状态栏内的小图标 .setContentText("服务运行中,使用菜单[暂停服务]退出...") // 设置上下文内容 .setWhen(System.currentTimeMillis()); // 设置该通知发生的时间 Notification notification = builder.build(); // 获取构建好的Notification notification.defaults=Notification.DEFAULT_SOUND; //设置为默认的声音 startForeground(ForegroundId, notification); runnable.run(); super.onCreate(); } //===========联合使用Handler与Runable实现类似闹钟的效果 ==== private Handler handler=new Handler();//不需要编写handler的消息处理代码 //Runnable只是一个接口通常需要关联到线程 private Runnable runnable=new Runnable() { @Override public void run() { // TODO Auto-generated method stub //要做的事情 Log.d(TAG, "---Run---"); MNotifyDao dao=new MNotifyDao(getApplicationContext()); List<MNotifyModel> notifies= dao.loadAliveNotifies(); for (MNotifyModel mIt : notifies) { //不需要提醒服务 if(!mIt.isUseNotifyServer()){ continue; } //检测是否设置忽略了 if(mIt.getLastIgnoreTime()!=null){ String actDate = DateUtil.formatShort(mIt .getLastIgnoreTime()); String curDate = DateUtil.formatShort(new Date()); if (actDate.compareToIgnoreCase(curDate) == 0) { continue;//跳到下一个 } } //检测是否执行了今天 if(mIt.getLastActTime()!=null){ String actDate = DateUtil.formatShort(mIt .getLastActTime()); String curDate = DateUtil.formatShort(new Date()); if (actDate.compareToIgnoreCase(curDate) == 0) { continue;//跳到下一个 } } //设定时间小于当前时间 Date curDate=new Date(); String waringTime= DateUtil.formatShort(curDate)+" " +mIt.getWaringTime() +":00"; if( DateUtil.parse(waringTime).after(curDate)){ continue; } //提醒过了需要等30分钟再次提醒 if(mIt.getLastNotifyTime()!=null){ Long diffMicSec=curDate.getTime() -mIt.getLastNotifyTime().getTime(); Log.d(TAG, String.valueOf(diffMicSec)); if(diffMicSec < 1000*60*30){ //小于30分钟 continue; } } mIt.setLastNotifyTime(curDate); dao.update(mIt); //启动提醒窗体 Intent intent = new Intent(getApplicationContext(), MedicineAlarmActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction("NotificationClick"); String note="接收消息:\r\n" +mIt.getMsg() +"\r\n 设定时间:\r\n"+mIt.getWaringTime(); intent.putExtra("Note",note); intent.putExtra("AddTime", DateUtil.formatLong(curDate)); startActivity(intent); break; } //---------间隔时间-------------------- Integer loopInterval=MedicineSetting.getLoopInterval(getApplicationContext()); handler.postDelayed(this, loopInterval*1000*60); } }; //=================End============= @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand()"); // 在API11之后构建Notification的方式 return Service.START_REDELIVER_INTENT; } @Override public void onDestroy() { Log.d(TAG, "onDestroy"); handler.removeCallbacks(runnable); stopForeground(true); super.onDestroy(); } private static final String TAG = "TestMNotify"; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } }