Android - Running a background task every 15 minutes, even when application is not running
You have have detemined the amount of time (interval) to execute a snippet of code, its better to use AlarmManager because its more energy effient. If your app needs to listen to some sort of a event , then Service is what you need.
public static void registerAlarm(Context context) {
Intent i = new Intent(context, YOURBROADCASTRECIEVER.class);
PendingIntent sender = PendingIntent.getBroadcast(context,REQUEST_CODE, i, 0);
// We want the alarm to go off 3 seconds from now.
long firstTime = SystemClock.elapsedRealtime();
firstTime += 3 * 1000;//start 3 seconds after first register.
// Schedule the alarm!
AlarmManager am = (AlarmManager) context
.getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime,
600000, sender);//10min interval
}
Need to have one background task to run for every minute in android
Work manager can only work within 15 minutes of interval, if you do not define a longer time. To run something every minute, you need a Foreground Service with a sticky notification in it. There is no other way to run something every minute.
To start a foreground service, create a service as usual, and in its onStartCommand
, call startForeground
and from the method, return START_STICKY
. These should achieve what you need.
Edit: Sample code for handler thread (this is Java btw, should be similar on Xamarin):
private HandlerThread handlerThread;
private Handler backgroundHandler;
@Override
public int onStartCommand (params){
// Start the foreground service immediately.
startForeground((int) System.currentTimeMillis(), getNotification());
handlerThread = new HandlerThread("MyLocationThread");
handlerThread.setDaemon(true);
handlerThread.start();
handler = new Handler(handlerThread.getLooper())
// Every other call is up to you. You can update the location,
// do whatever you want after this part.
// Sample code (which should call handler.postDelayed()
// in the function as well to create the repetitive task.)
handler.postDelayed(() => myFuncToUpdateLocation(), 60000);
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
handlerThread.quit();
}
How to run background task erveryday at 6:30PM
On Android, you can use AlarmManager
if version<=19, use JobScheduler
if version>20. Here is the demo on github.
Like this:
public void startTask()
{
if (Build.VERSION.SdkInt <= BuildVersionCodes.Kitkat)
{
AlarmManager alarmManager = (AlarmManager)GetSystemService(Context.AlarmService);
Intent intent = new Intent(this, typeof(RepeatingAlarm));
PendingIntent sender = PendingIntent.GetBroadcast(this, 0, intent, 0);
// Schedule the alarm!
alarmManager.SetRepeating(AlarmType.RtcWakeup, SystemClock.ElapsedRealtime(), 5 * 1000, sender);
}
else
{
JobScheduler scheduler = (JobScheduler)GetSystemService(Context.JobSchedulerService);
if (isJobPollServiceOn())
{
}
else
{
JobInfo jobInfo = new JobInfo.Builder(1,
new ComponentName(this, Java.Lang.Class.FromType(typeof(JobSchedulerService))))
.SetPeriodic(1000*5)
.Build();
scheduler.Schedule(jobInfo);
}
}
}
isJobPollServiceOn
method:
[TargetApi(Value = 20)]
public bool isJobPollServiceOn()
{
JobScheduler scheduler = (JobScheduler)GetSystemService(Context.JobSchedulerService);
bool hasBeenScheduled = false;
var jobInfos = scheduler.AllPendingJobs;
for (int i = 0; i < jobInfos.Count; i++)
{
if (jobInfos[i].Id == 1)
{
hasBeenScheduled = true;
break;
}
}
return hasBeenScheduled;
}
Android background process loading data from webpage every minute
Easy with WorkManager
, it's the most encouraged way for Scheduling Repeating background work in Android, see introduction.
As you say, the minimum repeating work request interval is restricted to 15 minutes, the only way to break it is to Repeatedly schedule the one-time work.
1. Setup Your Worker Class:
class ToastShower(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
withContext(Dispatchers.Main) { //ui related work must run in Main thread!!
Toast.makeText(applicationContext, "Hey, I'm Sam! This message will appear every 5 seconds.", Toast.LENGTH_SHORT).show()
}
return Result.success()
}
}
2. Setup Your Custom Application Class:
class WorkManagerApplication : Application() {
private val backgroundScope = CoroutineScope(Dispatchers.Default) //standard background thread
private val applicationContext = this
override fun onCreate() { //called when the app launches (same as Activity)
super.onCreate()
initWork()
}
private fun initWork() {
backgroundScope.launch { //all rnu in background thread
setupToastShowingWork(0) //no delay at first time
observeToastShowingWork() //observe work state changes, see below
}
}
private fun setupToastShowingWork(delayInSeconds: Long) { //must run in background thread
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED) //when using WiFi
.build()
val oneTimeRequest = OneTimeWorkRequestBuilder<ToastShower>() //【for breaking 15 minutes limit we have to use one time request】
.setInitialDelay(delayInSeconds, TimeUnit.SECONDS) //customizable delay (interval) time
.setConstraints(constraints)
.build()
WorkManager.getInstance(applicationContext).enqueueUniqueWork( //【must be unique!!】
ToastShower::class.java.simpleName, //work name, use class name for convenient
ExistingWorkPolicy.KEEP, //if new work comes in with same name, discard the new one
oneTimeRequest
)
}
private suspend fun observeToastShowingWork() {
withContext(Dispatchers.Main) { //must run in Main thread for using observeForever
WorkManager.getInstance(applicationContext).getWorkInfosForUniqueWorkLiveData(ToastShower::class.java.simpleName).observeForever {
if (it[0].state == WorkInfo.State.SUCCEEDED) { //when the work is done
backgroundScope.launch { //prevent from running in Main thread
setupToastShowingWork(5) //every 5 seconds
}
}
}
}
}
}
3. Setup AndroidManifest File:
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.workmanagertest">
<application
android:name=".WorkManagerApplication" //【here, must!!!】
...
</application>
</manifest>
By setting up with above, the work (showing Toast
in my example) will be executed (or more clearly, schedule and execute) every 5 seconds no matter the app is in foreground or background or killed by system. Only way to stop it is either uninstall or go inside the app's setting to force-close it.
Demo: https://youtu.be/7IsQQppKqFs
Related Topics
Convert Html/Mxml File to Word Doc Programmatically in Java
How to Send Parallel Get Requests and Wait for Result Responses
Android Webview Displaying Blank Page
Intellij Idea - Gradle: Execution Failed for Task ':Compilejava'
How to Evaluate a Math Expression Given in String Form
Using Comparable to Compare Generic Variables
How to Externalize Application.Properties in Tomcat Webserver for Spring
How to Mock JPA Repository'S Save Method in Unit Tests
Random Number Generation Without Repetition in Java
How to Filter Nested Loops Using Java 8 Streams and Filters
Org.Hibernate.Annotationexception: @Onetoone or @Manytoone on <Entity> References an Unknown Entity
Map Json String Column of a JPA Entity to Java Object Automatically
Typecasting an Object from Parent Class to Child
How to Set the Radio Button Based on the Value Fetched from the Database
Spring Boot Required Request Part 'File' Is Not Present
How to Remove All Special Character in a String Except Dot and Comma