运行固定时间后每天一个方法
Run a method daily after a fixed time
我的应用程序中有一个功能,用户可以 select 在他想要从应用程序获取通知的时间。在这种情况下,我以这种格式 12:00 AM
从用户那里获取输入。我写了一个在我的应用程序中创建通知的方法,它工作正常,但我想每天在用户 selected 时间调用该方法。此外,如果应用程序完全被破坏,甚至 运行 在后台,此方法是否会在每天用户 selected 时间调用?
String user_time=tinyDB.getString("app_check_time"); // This is user selected time e.g, 12:00 PM
Calendar calendar = Calendar.getInstance();
Date date1 = null;
try {
date1=new SimpleDateFormat("h:m a").parse(user_time);
} catch (ParseException e) {
e.printStackTrace();
}
calendar.set(Calendar.HOUR_OF_DAY, date1.getHours());
calendar.set(Calendar.MINUTE, date1.getMinutes());
Date time = calendar.getTime();
System.out.println("hourr "+time);
timer = new Timer();
timer.schedule(new createNotification(), time);
您是否考虑过使用像 Quartz Scheduler 这样的东西?该库有一种机制,可以使用类似 cron 的表达式(查看 CronScheduleBuilder)在每天设定的时间段将任务安排到 运行。
一些示例代码(未测试):
public class GetDatabaseJob implements InterruptableJob
{
public void execute(JobExecutionContext arg0) throws JobExecutionException
{
getFromDatabase();
}
}
public class Example
{
public static void main(String[] args)
{
JobDetails job = JobBuilder.newJob(GetDatabaseJob.class);
// Schedule to run at 5 AM every day
ScheduleBuilder scheduleBuilder =
CronScheduleBuilder.cronSchedule("0 0 5 * * ?");
Trigger trigger = TriggerBuilder.newTrigger().
withSchedule(scheduleBuilder).build();
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.scheduleJob(job, trigger);
scheduler.start();
}
}
前期的工作有点多,您可能需要重写您的作业执行代码,但它应该让您更好地控制您希望作业如何 运行。如果您需要,更改时间表也会更容易
您可以为此使用 WorkManager。是的,它会 运行 即使你的应用程序完全死了。
来自 Android Docs:
WorkManager is a library used to enqueue deferrable work that is guaranteed to execute sometime after its Constraints are met.
您可以在此处查看指南https://developer.android.com/topic/libraries/architecture/workmanager
The WorkManager API makes it easy to schedule deferrable, asynchronous tasks that are expected to run even if the app exits or device restarts.
希望对您有所帮助!
为此任务创建一个长 运行 服务
Intent intent = new Intent(this, ReminderService.class);
startService(intent);
创建扩展服务的提醒服务
public class ReminderService extends Service {
@Override
public void onCreate() {
Calendar calendar = Calendar.getInstance();
calendar.set(calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH),
6,
0,
0);
setAlarm(calendar.getTimeInMillis());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// If we get killed, after returning from here, restart
return START_STICKY;
}
public void setAlarm(long timeInMillis) {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, ReminderReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,
0, intent, 0);
if (alarmManager != null) {
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, timeInMillis,
2 * 60 * 1000 , pendingIntent); //AlarmManager.INTERVAL_DAY //2 * 60 * 1000 (2 minutes)
}
}
}
创建扩展 BroadcastReceiver 的 ReminderReceiver
public class ReminderReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//do task to show notification
ShowNotification showNotification = new ShowNotification(context);
showNotification.showNotification("Method called");
}
}
创建 ShowNotification class
public class ShowNotification {
private static final int NOTIFICATION = 0;
private static final String NOTIFICATION_CHANNEL_ID = "100";
private Context context;
private NotificationManager notificationManager;
private ConnectivityManager conManager;
public ShowNotification(Context context) {
this.context = context;
if (notificationManager == null) {
notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
}
if (conManager == null) {
conManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
}
}
/**
* Show a notification while this service is running.
*
* @param key
*/
void showNotification(String key) {
String NOTIFICATION_CHANNEL_NAME = "NOTIFICATION_CHANNEL_NAME";
// In this sample, we'll use the same text for the ticker and the expanded notification
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
NOTIFICATION_CHANNEL_NAME, importance);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
notificationManager.createNotificationChannel(notificationChannel);
}
final Intent notificationIntent = new Intent(context, SplashActivity.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
// Set the info for the views that show in the notification panel.
Notification notification = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(android.R.drawable.ic_dialog_alert)
.setWhen(System.currentTimeMillis())
.setContentTitle("Method Called")
.setContentText(key)
.setContentIntent(contentIntent)
.setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
.build();
// Send the notification.
notificationManager.cancel(NOTIFICATION);
notificationManager.notify(NOTIFICATION, notification);
}
}
在清单文件中
<service
android:name=".ReminderService"
android:enabled="true"
android:exported="false" />
<receiver android:name=".ReminderReceiver" />
我的应用程序中有一个功能,用户可以 select 在他想要从应用程序获取通知的时间。在这种情况下,我以这种格式 12:00 AM
从用户那里获取输入。我写了一个在我的应用程序中创建通知的方法,它工作正常,但我想每天在用户 selected 时间调用该方法。此外,如果应用程序完全被破坏,甚至 运行 在后台,此方法是否会在每天用户 selected 时间调用?
String user_time=tinyDB.getString("app_check_time"); // This is user selected time e.g, 12:00 PM
Calendar calendar = Calendar.getInstance();
Date date1 = null;
try {
date1=new SimpleDateFormat("h:m a").parse(user_time);
} catch (ParseException e) {
e.printStackTrace();
}
calendar.set(Calendar.HOUR_OF_DAY, date1.getHours());
calendar.set(Calendar.MINUTE, date1.getMinutes());
Date time = calendar.getTime();
System.out.println("hourr "+time);
timer = new Timer();
timer.schedule(new createNotification(), time);
您是否考虑过使用像 Quartz Scheduler 这样的东西?该库有一种机制,可以使用类似 cron 的表达式(查看 CronScheduleBuilder)在每天设定的时间段将任务安排到 运行。
一些示例代码(未测试):
public class GetDatabaseJob implements InterruptableJob
{
public void execute(JobExecutionContext arg0) throws JobExecutionException
{
getFromDatabase();
}
}
public class Example
{
public static void main(String[] args)
{
JobDetails job = JobBuilder.newJob(GetDatabaseJob.class);
// Schedule to run at 5 AM every day
ScheduleBuilder scheduleBuilder =
CronScheduleBuilder.cronSchedule("0 0 5 * * ?");
Trigger trigger = TriggerBuilder.newTrigger().
withSchedule(scheduleBuilder).build();
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.scheduleJob(job, trigger);
scheduler.start();
} }
前期的工作有点多,您可能需要重写您的作业执行代码,但它应该让您更好地控制您希望作业如何 运行。如果您需要,更改时间表也会更容易
您可以为此使用 WorkManager。是的,它会 运行 即使你的应用程序完全死了。
来自 Android Docs:
WorkManager is a library used to enqueue deferrable work that is guaranteed to execute sometime after its Constraints are met.
您可以在此处查看指南https://developer.android.com/topic/libraries/architecture/workmanager
The WorkManager API makes it easy to schedule deferrable, asynchronous tasks that are expected to run even if the app exits or device restarts.
希望对您有所帮助!
为此任务创建一个长 运行 服务
Intent intent = new Intent(this, ReminderService.class);
startService(intent);
创建扩展服务的提醒服务
public class ReminderService extends Service {
@Override
public void onCreate() {
Calendar calendar = Calendar.getInstance();
calendar.set(calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH),
6,
0,
0);
setAlarm(calendar.getTimeInMillis());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// If we get killed, after returning from here, restart
return START_STICKY;
}
public void setAlarm(long timeInMillis) {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, ReminderReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,
0, intent, 0);
if (alarmManager != null) {
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, timeInMillis,
2 * 60 * 1000 , pendingIntent); //AlarmManager.INTERVAL_DAY //2 * 60 * 1000 (2 minutes)
}
}
}
创建扩展 BroadcastReceiver 的 ReminderReceiver
public class ReminderReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//do task to show notification
ShowNotification showNotification = new ShowNotification(context);
showNotification.showNotification("Method called");
}
}
创建 ShowNotification class
public class ShowNotification {
private static final int NOTIFICATION = 0;
private static final String NOTIFICATION_CHANNEL_ID = "100";
private Context context;
private NotificationManager notificationManager;
private ConnectivityManager conManager;
public ShowNotification(Context context) {
this.context = context;
if (notificationManager == null) {
notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
}
if (conManager == null) {
conManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
}
}
/**
* Show a notification while this service is running.
*
* @param key
*/
void showNotification(String key) {
String NOTIFICATION_CHANNEL_NAME = "NOTIFICATION_CHANNEL_NAME";
// In this sample, we'll use the same text for the ticker and the expanded notification
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
NOTIFICATION_CHANNEL_NAME, importance);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
notificationManager.createNotificationChannel(notificationChannel);
}
final Intent notificationIntent = new Intent(context, SplashActivity.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
// Set the info for the views that show in the notification panel.
Notification notification = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(android.R.drawable.ic_dialog_alert)
.setWhen(System.currentTimeMillis())
.setContentTitle("Method Called")
.setContentText(key)
.setContentIntent(contentIntent)
.setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
.build();
// Send the notification.
notificationManager.cancel(NOTIFICATION);
notificationManager.notify(NOTIFICATION, notification);
}
}
在清单文件中
<service
android:name=".ReminderService"
android:enabled="true"
android:exported="false" />
<receiver android:name=".ReminderReceiver" />