【问题标题】:Schedule a TimerTask at specific time once per day in a service in android在android中的服务中每天在特定时间安排一次TimerTask
【发布时间】:2025-12-17 21:55:01
【问题描述】:

我有一个TimerTask 对象timerTask。我的代码正在运行,但是当服务最初启动时,我的计时器任务会在指定时间之前立即运行,即下午 3:30,尽管我希望它每天只在下午 3:30 运行一次。

Calendar cal = Calendar.getInstance();
cal.set(Calendar.AM_PM, Calendar.PM);
cal.set(Calendar.HOUR, 3);    
cal.set(Calendar.MINUTE, 30);
cal.set(Calendar.SECOND, 0);
Date date = cal.getTime();
timer.schedule(timerTask, date, 1000*60*60*24); // once per day

【问题讨论】:

  • 不要不要为此使用TimerTask。您的进程将在这一天过去很久之前终止。使用AlarmManager
  • 但是我正在动态更改指定时间并从数据库中获取它,当我的警报管理器开始活动时,我将如何获得新时间。

标签: android service timer android-service timertask


【解决方案1】:

正如其他社区用户所建议的,不要使用 Timertask,android 有一个 AlarmManager

你可以使用。

怎么做?

  1. 使用广播接收器注册警报管理器,覆盖 onReceive 方法(触发 alamr 时的操作)
  2. 使用每天的间隔和要执行的时间设置警报。

这里以片段为例:

public class MainActivity extends Activity {
private static final String TAG ="MainActivity";
PendingIntent myPendingIntent;
AlarmManager alarmManager;
BroadcastReceiver myBroadcastReceiver;
Calendar firingCal;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //Register AlarmManager Broadcast receive.
    firingCal= Calendar.getInstance();
    firingCal.set(Calendar.HOUR, 8); // At the hour you want to fire the alarm
    firingCal.set(Calendar.MINUTE, 0); // alarm minute 
    firingCal.set(Calendar.SECOND, 0); // and alarm second
    long intendedTime = firingCal.getTimeInMillis();
    
    registerMyAlarmBroadcast();
    alarmManager.set( AlarmManager.RTC_WAKEUP, intendedTime , AlarmManager.INTERVAL_DAY , myPendingIntent );
}
 
private void registerMyAlarmBroadcast()
{
      Log.i(TAG, "Going to register Intent.RegisterAlramBroadcast");

    //This is the call back function(BroadcastReceiver) which will be call when your 
    //alarm time will reached.
    myBroadcastReceiver = new BroadcastReceiver()
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            Log.i(TAG,"BroadcastReceiver::OnReceive()");
            Toast.makeText(context, "Your Alarm is there", Toast.LENGTH_LONG).show();
        }
    };

    registerReceiver(myBroadcastReceiver, new IntentFilter("com.alarm.example") );
    myPendingIntent = PendingIntent.getBroadcast( this, 0, new Intent("com.alarm.example"),0 );
    alarmManager = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
}
private void UnregisterAlarmBroadcast()
{
    alarmManager.cancel(myPendingIntent); 
    getBaseContext().unregisterReceiver(myBroadcastReceiver);
}

@Override
protected void onDestroy() {
    unregisterReceiver(myBroadcastReceiver);
    super.onDestroy();
}
}

编辑:

如果时间可以根据用户输入在应用程序中动态更改,则只需更改日历的触发变量以调整时间。

【讨论】:

  • 但时间不是固定的,它在我的应用程序中动态变化。
  • @ZeeshanAliSayyed,好的 tnxs 澄清一下,我更新了答案
  • 嗨@Xoce,如果设备重新启动或关闭并再次打开会怎样。