使用AlarmManager在Android应用程序中每个午夜运行代码



我在这里看到了这个答案 https://stackoverflow.com/a/24198314/7767733 但无法让它工作。

我有一个函数refreshStuff()可以刷新片段的值。我在制作片段时、用户更新值时以及onResume()期间调用此函数。我还想在午夜强制刷新,这在用户只是看着屏幕而不做任何事情时是相关的。

但是我不确定如何在MyFragment课上设置它。我试过了:

public class MyFragment extends Fragment {
    ...
    private AlarmManager alarmMgr;
    private PendingIntent alarmIntent;
    private Context context;
    ...
    //in onCreate method
    context = getActivity();
    alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, AlarmReceiver.class);
    alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
    //midnight I hope
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis()); //do I even need this?
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        AlarmManager.INTERVAL_DAY, alarmIntent);

如果我理解答案,我必须在某处添加此方法:

@Override
public void onReceive(Context context, Intent intent) {
   refreshStuff();
} 

但是,我在任何地方都没有AlarmReceiver,我不知道在哪里放置onReceive()或必须在清单中定义什么。我也不知道收到后是否必须"关闭"?("警报"是否在不应该"堆叠"的时候"堆叠"?

否则,到目前为止,这是正确的方法吗?

编辑:

我尝试实现CommonsWare的答案:

public class MyFragment extends Fragment implements Runnable, SomeOtherListenersIUse, YetAnotherListenerEtc {
    private View viewForDisplayingTotals;
    //...rest of implementation omitted for brevity
    @Override
    public void run() {
        refreshValues();
    }
    @Override
    public void onStart() {
        super.onStart();
        refreshValues();
        viewForDisplayingTotals.postDelayed(this, HelperMethods.getMillisecondsTillNextMidnight());
    }
    @Override
    public void onStop() {
        super.onStop();
        viewForDisplayingTotals.removeCallbacks(this);
    }
}

我的助手方法:

public static long getMillisecondsTillNextMidnight() {
    Calendar c = Calendar.getInstance();
    c.add(Calendar.DAY_OF_MONTH, 1); //add a day first
    c.set(Calendar.HOUR_OF_DAY, 0); //then set the other fields to 0
    c.set(Calendar.MINUTE, 0);
    c.set(Calendar.SECOND, 0);
    c.set(Calendar.MILLISECOND, 0);
    return c.getTimeInMillis() - System.currentTimeMillis();
}

摆脱所有AlarmManager的东西。这是当您想在特定时间在后台获得控制权时,在您的情况下,这只是您在前台时的问题。

步骤#1:将implements Runnable添加到MyFragment定义

步骤#2:这将要求您实现run()方法,并在其中调用refreshStuff()

步骤#3:在onResume()(或者更好的是onStart()(,当您调用refreshStuff()时,还可以通过一些方便的View调用postDelayed(this, ...),其中...是从现在到下一个午夜之间的毫秒数

步骤#4:在onPause()(或者更好的是onStop()(,在同一View上呼叫removeCallbacks(this)

这将导致您的run()方法在午夜左右被调用,您将在其中调用refreshStuff()

我什至需要这个吗?

是的。但请注意,您的计算是针对过去的午夜,忽略秒数。 add()一天,考虑使用set()将秒数归零。

最新更新