使用 GcmTaskService 在特定时间通知

Notifications at specific hour using GcmTaskService

我需要帮助 运行在一天中的特定时间收到通知。我搜索过但一无所获。

我正在使用 GCMTaskService 我有一个 PeriodicTask,目前 运行 每 24 小时执行一次任务。我希望每天下午 4 点 运行。知道我能做到吗?

这是目前的周期性任务:

    long periodSecs = 86400L;
    long flexSecs = 15L;

    String tag = "periodic  | " + taskID++ + ": " + periodSecs + "s, f:" + flexSecs;  // a unique task identifier

    periodic = new PeriodicTask.Builder()
            .setService(MyTasksService.class)
            .setPeriod(periodSecs)
            .setFlex(flexSecs)
            .setTag(tag)
            .setPersisted(true)
            .setRequiredNetwork(Task.NETWORK_STATE_CONNECTED)
            .setRequiresCharging(false)
            .build();
    GcmNetworkManager.getInstance(this).schedule(periodic);

这是我的 GCMTaskService Class:

public class MyTasksService extends GcmTaskService {

public MyTasksService() {
    super();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return super.onStartCommand(intent, flags, startId);
}

@Override
public IBinder onBind(Intent intent) {
    Log.i("myTaskService", "onBind");
    return super.onBind(intent);
}

@Override
public void onInitializeTasks() {
    super.onInitializeTasks();
    Log.i("myTaskService", "onInitializeTasks");
}

@Override
public int onRunTask(TaskParams taskParams) {
    Log.i("myTaskService", "onRunTask");
    SendPushNotification.dailyNewsPush();
    SendPushNotification.dailyLecturasPush();
    return 0;
   }
}

这很难做到的原因是 API 不是故意为它设计的。就服务器负载而言,每天都在同一时间访问服务器不是一个好主意。

例如如果您有 1000 人使用您的应用程序每天向您的服务器签入 1 次,您的 QPS 将为 1000/(24 * 60 * 60) = 0.011.

如果您希望每个人都在下午 3 点访问服务器,您的 QPS 将为 1000。随着安装量的增长,情况会变得更糟。

如果您托管自己的服务器,您将不得不启动额外的容量来应对这种巨大的峰值,如果您租用服务器,您将需要支付大量费用来启动实例来应对上述情况。

如果您只是为了测试应用程序或用户群较小的应用程序而这样做,这仍然不是一个好主意,因为您不知道将来会有多少用户。 但是,您始终可以计算到您想要的挂钟时间之前的秒数,并使用它来安排任务。

使用 java 日历可能是最简单的方法。释义:

Calendar currentCal = Calendar.getInstance();
Calendar 3amCal = Calendar.getInstance();
3amCal.set(Calendar.HOUR_OF_DAY, 3);
if (3amCal.before(currentCal)) {
  // it's past 3 am, roll forward
  3amCal.add(Calendar.DATE, 1);
}
final long 3amTomorrow = 3amCal.getTime();
final long current = currentCal.getTime();
final long millisUntil3amTomorrow = 3amTomorrow - currentTime;