I have an app that I have created where I want the app to run a single method when the the time reaches 00:00 (basically the next day).
For context, my app saves a csv file for each day. I've research around on how to make apps run in the background and foreground services was the the one that I found, but I feel like it is too overkill as my app will only run one method, once, each day (the method in question is the one that creates the csv file).
Is foreground services my only option or are there other ways to do this?
For these kind of tasks which runs on specific dates or time or run the task periodically on the bases of date or time. It is recommended to use AlarmManager. Here is the implementation
Kotlin
class DailyTaskBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
yourTask()
}
}
class MyApplication: Application() {
override fun onCreate() {
super.onCreate()
// Initiate your task
scheduleDailyTask(this)
}
fun scheduleDailyTask(context: Context) {
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent = Intent(context, DailyTaskBroadcastReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_NO_CREATE or PendingIntent.FLAG_IMMUTABLE)
// If the alarm is not already set, schedule it
if (pendingIntent == null) {
val calendar = Calendar.getInstance().apply {
timeInMillis = System.currentTimeMillis()
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
add(Calendar.DAY_OF_YEAR, 1) // Set to the next day
}
// Set the alarm to trigger at midnight every day
alarmManager.setRepeating(
AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
AlarmManager.INTERVAL_DAY,
PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
)
}
}
JAVA
public class DailyTaskBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
yourTask();
}
}
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// Initiate your task
scheduleDailyTask(this);
}
public void scheduleDailyTask(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, DailyTaskBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE);
// If the alarm is not already set, schedule it
if (pendingIntent == null) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.add(Calendar.DAY_OF_YEAR, 1); // Set to the next day
// Set the alarm to trigger at midnight every day
alarmManager.setRepeating(
AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY,
PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
);
}
}
}
<receiver android:name=".DailyTaskBroadcastReceiver" />
Testing
To test you can simply update your scheduleDailyTask()
to trigger after every 1 minute:
// Alarm Schedule
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.MINUTE, 1); // Set to trigger after 1 minute initially
And also set the repetition
// Set the alarm to repeat every minute
alarmManager.setRepeating(
AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
60 * 1000, // 60 seconds * 1000 milliseconds
pendingIntent
);
// Try printing the Log in the BroadcastReceiver onCreate method to verify if it is triggering after every 1 minute.
}
Note: I didn't compile this code, please don't forget to add imports.
Reference: Check the more Calendar related tasks