每天在固定时间后运行一个方法。

huangapple go评论75阅读模式
英文:

Run a method daily after a fixed time

问题

我在我的应用程序中有一个功能,用户可以选择何时从应用程序收到通知。在这种情况下,我以12:00 AM的格式从用户那里获取输入。我编写了一个用于在我的应用程序中创建通知的方法,它运行良好,但我想每天在用户选择的时间调用该方法。此外,如果应用程序完全关闭,甚至不在后台运行,这个方法会每天在用户选择的时间被调用吗?

String user_time = tinyDB.getString("app_check_time"); // 这是用户选择的时间,例如,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);

请注意,这只是代码的翻译部分,没有其他内容。

英文:

I have functionality in my app where a user will select the time when he wants to get notifications from the application. In this case, I am taking the input from user in this format 12:00 AM. I wrote a method for creating notifications in my app which is working fine but I want to call that method every day at a user-selected time. Also, if app is completely destroyed not even running in the background will this method be called at the user-selected time daily?

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);

答案1

得分: 0

你考虑过使用类似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();
    }
}

这需要一些更多的初始工作,可能需要重写作业执行代码,但它可以让你更好地控制作业的运行方式。此外,如果需要更改计划,这也更容易。

英文:

Have you considered using something like Quartz Scheduler? This library has a mechanism for scheduling tasks to run at a set period of time every day using a cron like expression (take a look at CronScheduleBuilder).

Some example code (not tested):

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();

}
}

There's a bit more work upfront, and you may need to rewrite your job execution code, but it should give you more control over how you want you job to run. Also it would be easier to change the schedule should you need to

答案2

得分: 0

你可以使用WorkManager来实现这一点。是的,即使您的应用程序完全关闭,它也会运行。

来自Android文档

WorkManager是一个库,用于排队延迟执行的工作,确保在其约束满足后的某个时间执行。

您可以在这里查看指南:https://developer.android.com/topic/libraries/architecture/workmanager

WorkManager API使得轻松调度可延迟的异步任务变得简单,这些任务预计会在应用程序退出或设备重新启动时运行。

希望对您有帮助!

英文:

You can use WorkManager for this. And yes, it'll run even if your app is completely dead.

From Android Docs:

>> WorkManager is a library used to enqueue deferrable work that is guaranteed to execute sometime after its Constraints are met.

You can see the guide here 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.

Hope it helps!

答案3

得分: 0

创建一个长时间运行的任务服务

Intent intent = new Intent(this, ReminderService.class);
startService(intent);

创建一个扩展服务的ReminderService类

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) {
        // 如果服务被终止,在返回后重新启动
        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分钟)
        }
    }
}

创建一个扩展广播接收器的ReminderReceiver类

public class ReminderReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // 执行任务以显示通知
        ShowNotification showNotification = new ShowNotification(context);
        showNotification.showNotification("方法被调用");
    }
}

创建ShowNotification类

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);
        }
    }

    /**
     * 在此服务运行时显示通知。
     *
     * @param key
     */
    void showNotification(String key) {
        String NOTIFICATION_CHANNEL_NAME = "NOTIFICATION_CHANNEL_NAME";

        // 在此示例中,我们将在跑马灯和扩展通知中使用相同的文本
        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);

        // 如果用户选择此通知,则启动我们的活动的PendingIntent
        PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
                notificationIntent, 0);

        // 设置在通知面板中显示的视图的信息。
        Notification notification = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
                .setSmallIcon(android.R.drawable.ic_dialog_alert)
                .setWhen(System.currentTimeMillis())
                .setContentTitle("方法被调用")
                .setContentText(key)
                .setContentIntent(contentIntent)
                .setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
                .build();

        // 发送通知。
        notificationManager.cancel(NOTIFICATION);
        notificationManager.notify(NOTIFICATION, notification);
    }
}

在清单文件中

<service
    android:name=".ReminderService"
    android:enabled="true"
    android:exported="false" />

<receiver android:name=".ReminderReceiver" />
英文:

Creating a long running service for this task

Intent intent = new Intent(this, ReminderService.class);
startService(intent);

Creating a reminderservice which extends service

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)
}
}
}

creating ReminderReceiver which extends BroadcastReceiver

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(&quot;Method called&quot;);
}
}

create ShowNotification class

public class ShowNotification {
private static final int NOTIFICATION = 0;
private static final String NOTIFICATION_CHANNEL_ID = &quot;100&quot;;
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 = &quot;NOTIFICATION_CHANNEL_NAME&quot;;
// In this sample, we&#39;ll use the same text for the ticker and the expanded notification
if (android.os.Build.VERSION.SDK_INT &gt;= 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(&quot;Method Called&quot;)
.setContentText(key) 
.setContentIntent(contentIntent)  
.setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
.build();
// Send the notification.
notificationManager.cancel(NOTIFICATION);
notificationManager.notify(NOTIFICATION, notification);
}
}

In manifest file

        &lt;service
android:name=&quot;.ReminderService&quot;
android:enabled=&quot;true&quot;
android:exported=&quot;false&quot; /&gt;
&lt;receiver android:name=&quot;.ReminderReceiver&quot; /&gt;

huangapple
  • 本文由 发表于 2020年1月3日 14:31:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/59574134.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定