android - 在准确的时间使用 Job Scheduler 执行后台任务
问题描述
我正在开发新闻应用程序。而且我需要每天获得一次最新消息。为此,我使用了 Jobsheduler。这是代码:
ComponentName componentName = new ComponentName(this, JobService.class);
JobInfo jobInfo = new JobInfo.Builder(123, componentName)
.setRequiresCharging(false)
.setPeriodic(24 * 60 * 60 * 1000)
.setPersisted(true)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.build();
JobScheduler jobScheduler = (JobScheduler)getApplicationContext().getSystemService(JOB_SCHEDULER_SERVICE);
int resultCode = jobScheduler.schedule(jobInfo);
if (resultCode == JobScheduler.RESULT_SUCCESS){
Log.d(TAG, "Job Scheduled");
}
else {
Log.d(TAG, "Job Scheduling failed");
}
但现在我需要在早上 6:00 之后做一次这项工作,届时将有互联网连接。有没有办法用 Job Scheduler 做到这一点。我知道我可以使用警报管理器来做到这一点,但在有连接、设备充电等情况下,作业计划程序比警报管理器要好得多。或者,如果需要,我可以使用 Workmanager 来实现这一点,它使用 Job Scheduler 和 AlarmManager。或者还有其他方法吗???任何建议表示赞赏。
解决方案
public static final String CUSTOM_INTENT = "com.test.intent.action.ALARM";
public static Context ctx = OfferlyApplication.getContext();
@Override
public void onReceive(Context context, Intent intent) {
/* enqueue the job */
AlarmJobIntentService.enqueueWork(context, intent);
}
public static void cancelAlarm() {
AlarmManager alarm = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
/* cancel any pending alarm */
alarm.cancel(getPendingIntent());
}
public static void setAlarm(boolean force) {
cancelAlarm();
AlarmManager alarmManager = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
// EVERY X MINUTES
long delay = (1000 * 60 * 60);
long when = System.currentTimeMillis();
if (!force) {
when += delay;
}
/* fire the broadcast */
PendingIntent pendingIntent = getPendingIntent();
int SDK_INT = Build.VERSION.SDK_INT;
if (SDK_INT < Build.VERSION_CODES.KITKAT)
alarmManager.set(AlarmManager.RTC_WAKEUP, when, pendingIntent);
else if (SDK_INT < Build.VERSION_CODES.M)
alarmManager.setExact(AlarmManager.RTC_WAKEUP, when, pendingIntent);
else {
Log.d("JOB_SCHEDULING","waking device");
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, when, pendingIntent);
}
}
private static PendingIntent getPendingIntent() {
//Context ctx; /* get the application context */
Intent alarmIntent = new Intent(ctx, AlarmReceiver.class);
alarmIntent.setAction(CUSTOM_INTENT);
return PendingIntent.getBroadcast(ctx, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
}
或为定期工作人员使用工作管理器
Constraints myConstraints = new Constraints.Builder()
.setRequiresDeviceIdle(false)
.setRequiresCharging(false)
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresBatteryNotLow(true)
.setRequiresStorageNotLow(true)
.build();
PeriodicWorkRequest saveRequest =
new PeriodicWorkRequest.Builder(NotificationWorker.class, 60, TimeUnit.MINUTES)
.setConstraints(myConstraints)
.build();
WorkManager.getInstance()
.enqueue(saveRequest);
推荐阅读
- excel - 对日期相同但时间不同的单元格进行排序
- javascript - 检查嵌套数组是否包含 JavaScript 中另一个嵌套数组的任何元素
- kotlin - Kotlin 协程:并发执行节流
- c++ - SFML 错误中的字符串输入
- ios - indexDB 没有在 SFSafariViewController 中持久化
- sql - 我正在尝试执行每 30 秒执行一次的简单 SQL 代码
- python-3.x - 谁能解释一下 sklearn preprocessing.normalise 和 MinMaxScaler() 之间的区别
- android - 无法解析 IST 格式和 GMT 格式的字符串日期
- mongodb - 无法使用 mongodump 命令获取 mongodb 转储
- sql - 如何使用 MATCH_RECOGNIZE 获得所需的结果?