最后一部分是提醒以及每天任务刷新,两者都用到了
AlarmManager
这个系统管理类。
提醒
提醒功能就是一个闹钟的效果,只是这里是启动服务,在服务里发一条notification作为提醒。设置时间时,
TimePicker控件会监听该事件,每次时间改变后都会重新设置系统闹钟;如果用户关闭提醒功能的话,这个系统闹钟设置的事件也会取消。修改后的
SettingFragment如下:
<span style="font-size:24px;">@EFragment (R.layout.frag_setting )
public class SettingFragment extends BaseFragment {
@ColorRes(R.color. setting_text_dark)
int alarmColor;
@ColorRes(R.color. main_bg)
int remindColor;
@ViewById
ToggleButton tb_alarm;
@ViewById
TimePicker tp_alarm;
@Pref
GlobalPrefBean_ globalPrefBean;
private boolean initViewFinished;
@AfterViews
void AfterViews() {
initViewFinished = true;
tp_alarm.setIs24HourView( true);
Util. setNumberPickerTextSizeAndColor( tp_alarm, 25, alarmColor);
Util. resizeTimerPicker( tp_alarm, 100, LayoutParams.WRAP_CONTENT );
tp_alarm.setOnTimeChangedListener( new TimePicker.OnTimeChangedListener() {
@Override
public void onTimeChanged(TimePicker view, int hour, int min) {
onTimeSet(hour, min);
}
});
initView();
initPendingIntent();
}
@Override
public void show() {
if ( initViewFinished) {
initView();
}
}
void initView() {
String alarmTime = globalPrefBean .alarmTime().getOr("" );
if ( "".equals(alarmTime)) {
tp_alarm.setEnabled( false);
tb_alarm.setChecked( true);
tp_alarm.setCurrentHour(0);
tp_alarm.setCurrentMinute(0);
tb_alarm.setTextColor( remindColor);
} else {
int hour = Integer.parseInt(alarmTime.subSequence(0, 2).toString());
int min = Integer.parseInt(alarmTime.subSequence(2, 4).toString());
tp_alarm.setEnabled( true);
tb_alarm.setChecked( false);
tp_alarm.setCurrentHour(hour);
tp_alarm.setCurrentMinute(min);
tb_alarm.setTextColor( alarmColor);
setSystemAlarm(hour, min);
}
}
@Click
void tb_alarm() {
if ( tb_alarm.isChecked()) {
tp_alarm.setEnabled( false);
tp_alarm.setCurrentHour(0);
tp_alarm.setCurrentMinute(0);
tb_alarm.setTextColor( remindColor);
globalPrefBean.alarmTime().put( "");
cancelSystemAlarm();
} else {
tp_alarm.setEnabled( true);
tb_alarm.setTextColor( alarmColor);
globalPrefBean.alarmTime().put( "0000");
setSystemAlarm(0, 0);
}
}
void onTimeSet( int hour, int min) {
/*
* init alarm time; if it is empty originally, do nothing, else set the
* value to empty
*/
String alarmTime = globalPrefBean .alarmTime().getOr("" );
if ( "".equals(alarmTime)) {
return;
} else {
alarmTime = "";
}
if (hour < 10) {
alarmTime += "0";
}
alarmTime += "" + hour;
if (min < 10) {
alarmTime += "0";
}
alarmTime += "" + min;
globalPrefBean.alarmTime().put(alarmTime);
setSystemAlarm(hour, min);
}
@SystemService
AlarmManager alarmManager;
PendingIntent pi;
@Background
void initPendingIntent() {
Intent intent = new Intent(getActivity().getBaseContext(),
AlarmService_. class);
pi = PendingIntent. getService(getActivity(), 0, intent,
PendingIntent. FLAG_UPDATE_CURRENT);
}
@Background
void setSystemAlarm( int hour, int min) {
Calendar c = Calendar. getInstance();
c.setTimeInMillis(System. currentTimeMillis());
c.set(Calendar. HOUR_OF_DAY, hour);
c.set(Calendar. MINUTE, min);
c.set(Calendar. SECOND, 0);
c.set(Calendar. MILLISECOND, 0);
long intervalMillis = c.getTimeInMillis() > System.currentTimeMillis() ? c
.getTimeInMillis()
: (c.getTimeInMillis() + AlarmManager.INTERVAL_DAY );
alarmManager.setRepeating(AlarmManager. RTC, intervalMillis,
AlarmManager. INTERVAL_DAY, pi);
}
@Background
void cancelSystemAlarm() {
alarmManager.cancel( pi);
}
}</span>
AlarmService服务很简单,就是在每次启动时调用
onStartCommand方法,检查今天是否已经签到,没有的话发一条通知给用户作为提醒,具体代码如下:
@EService
public class AlarmService extends Service {
private MyDatabaseHelper dbHelper = null;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if ( dbHelper == null) {
dbHelper = new MyDatabaseHelper(getBaseContext(), "di.db3" , 1);
}
TaskBean task = DailyInsistDao.getcurrentTask( dbHelper);
if (task != null && !task.isDoneToday()) {
sendNotification();
}
return super.onStartCommand(intent, flags, startId);
}
@SystemService
NotificationManager nManager;
private void sendNotification() {
Intent intent = new Intent(AlarmService. this,
DailyInsistActivity_. class);
intent.setAction(Intent. ACTION_MAIN);
intent.addCategory(Intent. CATEGORY_LAUNCHER);
PendingIntent pi = PendingIntent.getActivity(AlarmService. this, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT );
@SuppressWarnings( "deprecation")
Notification notify = new Notification.Builder( this)
. setAutoCancel( true)
.setTicker( "来自DI的消息" )
.setSmallIcon(R.drawable. ic_launcher)
.setContentTitle( "一条新通知" )
.setContentText( "今天还有任务未签到~" )
.setDefaults(
Notification. DEFAULT_SOUND
| Notification.DEFAULT_LIGHTS )
.setWhen(System. currentTimeMillis()).setContentIntent(pi)
. getNotification();
nManager.notify(0xfff, notify);
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
任务刷新
任务刷新的功能,就是在每天零点重置当前任务的状态为未签到,前提条件是该任务还没有结束。更改后通知MainFragment界面做出相应的更新,这段代码加在了主Activity里,即程序启动后就设置该系统闹钟:
@SystemService
AlarmManager alarmManager;
/**
*
* @Method : setService
* @Description : use alarm manager to start a service that reset a task to
* not done everyday at 00:00:00
* @param
* @return void
* @throws
*/
@Background
void setService() {
Intent intent = new Intent(DailyInsistActivity. this,
ResetTaskService_. class);
PendingIntent pi = PendingIntent.getService(DailyInsistActivity. this,
0, intent, PendingIntent.FLAG_UPDATE_CURRENT );
Calendar c = Calendar. getInstance();
c.setTimeInMillis(System. currentTimeMillis());
c.set(Calendar. HOUR_OF_DAY, 0);
c.set(Calendar. MINUTE, 0);
c.set(Calendar. SECOND, 0);
c.set(Calendar. MILLISECOND, 0);
long intervalMillis = c.getTimeInMillis() + AlarmManager.INTERVAL_DAY ;
alarmManager. setRepeating(AlarmManager. RTC_WAKEUP, intervalMillis,
AlarmManager. INTERVAL_DAY, pi);
}
ResetTaskService服务也很简单,每次启动时调用
onStartCommand方法,若任务未完成,重置任务状态为未签到:
@EService
public class ResetTaskService extends Service {
private MyDatabaseHelper dbHelper = null;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if ( dbHelper == null) {
dbHelper = new MyDatabaseHelper(getBaseContext(), "di.db3" , 1);
}
TaskBean task = DailyInsistDao.getcurrentTask( dbHelper);
if (task != null && task.getCompleted() < task.getDuring()) {
DailyInsistDao. updateDoneState( dbHelper, task.getTaskId(), false );
getBaseContext().sendBroadcast(
new Intent(Actions.ACTION_UPDATE_MAIN_INFO ));
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
MainFragment中做了部分代码修改,接收广播后更新界面,具体代码请查看源代码。
最后,为了保证关机开机都会执行任务刷新,增加了一个接收系统消息开机和唤醒解锁的广播,设置系统闹钟:
@EReceiver
public class PushReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
setSystemAlarm(context);
setService(context);
}
@Pref
GlobalPrefBean_ globalPrefBean;
@SystemService
AlarmManager alarmManager;
@Background
void setSystemAlarm(Context context) {
int hour, min;
String alarmTime = globalPrefBean .alarmTime().getOr("" );
if ( "".equals(alarmTime)) {
return;
} else {
hour = Integer. parseInt(alarmTime.subSequence(0, 2).toString());
min = Integer. parseInt(alarmTime.subSequence(2, 4).toString());
}
Intent intent = new Intent(context, AlarmService_.class );
PendingIntent pi = PendingIntent. getService(context, 0, intent,
PendingIntent. FLAG_UPDATE_CURRENT);
Calendar c = Calendar .getInstance();
c.setTimeInMillis(System. currentTimeMillis());
c.set( Calendar. HOUR_OF_DAY, hour);
c.set( Calendar. MINUTE, min);
c.set( Calendar. SECOND, 0);
c.set( Calendar. MILLISECOND, 0);
long intervalMillis = c.getTimeInMillis() > System.currentTimeMillis() ? c
.getTimeInMillis()
: (c.getTimeInMillis() + AlarmManager.INTERVAL_DAY );
alarmManager.setRepeating(AlarmManager. RTC, intervalMillis,
AlarmManager. INTERVAL_DAY, pi);
}
@Background
void setService(Context context) {
Intent intent = new Intent(context, ResetTaskService_.class );
PendingIntent pi = PendingIntent. getService(context, 0, intent,
PendingIntent. FLAG_UPDATE_CURRENT);
Calendar c = Calendar .getInstance();
c.setTimeInMillis(System. currentTimeMillis());
c.set( Calendar. HOUR_OF_DAY, 0);
c.set( Calendar. MINUTE, 0);
c.set( Calendar. SECOND, 0);
c.set( Calendar. MILLISECOND, 0);
long intervalMillis = c.getTimeInMillis() + AlarmManager.INTERVAL_DAY ;
alarmManager.setRepeating(AlarmManager. RTC_WAKEUP, intervalMillis,
AlarmManager. INTERVAL_DAY, pi);
}
}
运行效果图: