Run a service in background continuously
Below code works for me...
public class AppService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
Toast.makeText(this, " MyService Created ", Toast.LENGTH_LONG).show();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, " MyService Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
}
Running Service Continuously - Delphi
This bit of code only runs when the service is started from the Windows Service Manager. Once you have your service .exe
file, use a command prompt to start it with the /install
command line argument, and use net start <your-service-name>
or the Service Management dailog from the Administrative Tools from the Start Menu or Control Panel to start the service.
If you want to run the service in the Delphi debugger, start Delphi with administrative privileges and attach to the running process. But it's more advisable to have all logic in separate units, and have a separate version of the project as a 'plain exe' the run the project's procedures that you can run in the debugger.
Continually Running Background Service
In oreo release Android defined limits to background services.
To improve the user experience, Android 8.0 (API level 26) imposes
limitations on what apps can do while running in the background.
Still if app need to run its service always, then we can create foreground service.
Background Service Limitations: While an app is idle, there are limits
to its use of background services. This does not apply to foreground
services, which are more noticeable to the user.
So create a foreground service. In which you will put a notification for user while your service is running. See this answer (There are many others)
Now what if you don't want a notification for your service. A solution is for that.
You can create some periodic task that will start your service, service will do its work and stops itself. By this your app will not be considered battery draining.
You can create periodic task with Alarm Manager, Job Scheduler, Evernote-Jobs or Work Manager.
- Instead of telling pros & cons of each one. I just tell you best. Work manager is best solution for periodic tasks. Which was introduced with Android Architecture Component.
- Unlike Job-Scheduler(only >21 API) it will work for all versions.
- Also it starts work after a Doze-Standby mode.
- Make a Android Boot Receiver for scheduling service after device boot.
I created forever running service with Work-Manager, that is working perfectly.
Running service on android 9.0 or higher continuously
you can use android.permission.BIND_NOTIFICATION_LISTENER_SERVICE
permission in your service
but you have to ask user for permission and also android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
permission for "doze-mode" then use a Thread
in the service for your BroadCastReceiver
. this way guaranteed to make your service always running but it will cost battery life . i have tried and tested this for my app from api-level 19 to 28 and never stopped even in some devices like nokia with android O
background running service disabled but with this trick you can keep it running. apps like Gameboosters or Cleaners also use this trick to keep there service alwyase running.
UPDATE:
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<service
android:name=".Service.NLService"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
>
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
Service
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public class NLService extends NotificationListenerService {
private static final String TAG = NLService.class.getSimpleName();
@Override
public void onCreate() {
super.onCreate();
new Thread(new Runnable() {
@Override
public void run() {
while (true)
try {
doSomeThing(NLService.this);
Thread.sleep(6000);
} catch (Exception ignore) {
}
}
}).start();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
doSomeThing(this);
}
@Override
public void onNotificationRemoved(StatusBarNotification sbn) {
doSomeThing(this);
}
Request Permission
private static final String ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS";
public void askForNotificationServicePermission() {
context.startActivity(new Intent(ACTION_NOTIFICATION_LISTENER_SETTINGS));
}
public void askForDozeModePermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent intent = new Intent();
String packageName = context.getPackageName();
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
context.startActivity(intent);
}
}
doSomeThing(this);
is some method that you want to run for example your broudcastreceiver.
Windows Service to run constantly
The OnStart()
callback needs to return in a timely fashion, so you'll want to kick off a thread where all your work will be performed. I would recommend adding the following fields to your class:
using System.Threading;
private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
private Thread _thread;
The _thread
field will hold a reference to the System.Threading.Thread
object you create in the OnStart()
callback. The _shutdownEvent
field holds a system-level event construct that will be used to signal the thread to stop running on service shutdown.
In the OnStart()
callback, create and start your thread.
protected override void OnStart(string[] args)
{
_thread = new Thread(WorkerThreadFunc);
_thread.Name = "My Worker Thread";
_thread.IsBackground = true;
_thread.Start();
}
You need a function named WorkerThreadFunc
in order for this to work. It has to match the System.Threading.ThreadStart
delegate signature.
private void WorkerThreadFunc()
{
}
If you don't put anything in this function, the thread will start up and then immediately shutdown, so you have to put some logic in there that basically keeps the thread alive while you do your work. This is where the _shutdownEvent
comes in handy.
private void WorkerThreadFunc()
{
while (!_shutdownEvent.WaitOne(0)) {
// Replace the Sleep() call with the work you need to do
Thread.Sleep(1000);
}
}
The while loop checks the ManualResetEvent
to see if it is "set" or not. Since we initialized the object with false
above, this check returns false. Inside the loop, we sleep for 1 second. You'll want to replace this with the work you need to do - monitor proxy settings, etc.
Finally, in the OnStop()
callback of your Windows Service, you want to signal the thread to stop running. This is easy using the _shutdownEvent
.
protected override void OnStop()
{
_shutdownEvent.Set();
if (!_thread.Join(3000)) { // give the thread 3 seconds to stop
_thread.Abort();
}
}
Hope this helps.
windows service is still running but the task is not executed continuously
The problem is, that your OnStart()
method already does the concrete job and never returns. But the Service Manager is designed, that it waits max 60 secs till the OnStart()
method returns, otherwise the process will be killed.
So, instead of directly calling within your OnStart()
method your code, you should instantiate a new Task or Thread that will do the work and immediately exit the OnStart()
method. Within the OnStop()
method you have to inform your parallel running code to stop (e.g. by using a CancellationToken
) and wait till it's done and then exit.
Example
public partial class ServiceExample : ServiceBase
{
public ServiceExample()
{
InitializeComponent();
}
private Task Runner;
private CancellationTokenSource Cts;
protected override void OnStart(string[] args)
{
if (Cts != null) // Could also simply return
throw new InvalidOperationException("Service is already running!");
Cts = new CancellationTokenSource();
Runner = DoSomething(Cts.Token);
}
private async Task DoSomething(CancellationToken cancellationToken)
{
// Immediately return to caller to avoid "hanging" OnStart()
await Task.Yield();
// Regulary check if OnStop() is waiting for us
while (!cancellationToken.IsCancellationRequested)
{
// Call your method that should do something.
// If it runs longer and can be intercepted,
// forward the CancellationToken to it.
await Worker(cancellationToken);
}
}
protected override void OnStop()
{
if (Cts == null) // Could also simply return
throw new InvalidOperationException("Service already being stopped!");
Cts.Cancel();
Runner.Wait();
}
private async Task Worker(CancellationToken cancellationToken)
{
Trace.WriteLine($"{DateTime.UtcNow}: Do some heavy work!");
await Task.Delay(TimeSpan.FromSeconds(1));
if (cancellationToken.IsCancellationRequested)
return;
await Task.Delay(TimeSpan.FromSeconds(1));
}
}
How to constantly run Python script in the background on Windows?
On Windows, you can use pythonw.exe
in order to run a python script as a background process:
Python scripts (files with the extension
.py
) will be executed bypython.exe
by default. This executable opens a terminal, which stays
open even if the program uses a GUI. If you do not want this to
happen, use the extension.pyw
which will cause the script to be
executed bypythonw.exe
by default (both executables are located in
the top-level of your Python installation directory). This suppresses
the terminal window on startup.
For example,
C:\ThanosDodd\Python3.6\pythonw.exe C:\\Python\Scripts\moveDLs.py
In order to make your script run continuously, you can use sched
for event scheduling:
The sched module defines a class which implements a general purpose
event scheduler
import sched
import time
event_schedule = sched.scheduler(time.time, time.sleep)
def do_something():
print("Hello, World!")
event_schedule.enter(30, 1, do_something, (sc,))
event_schedule.enter(30, 1, do_something, (s,))
event_schedule.run()
Now in order to kill a background process on Windows, you simply need to run:
taskkill /pid processId /f
Where processId
is the ID of the process you want to kill.
Background Service run continuously in Xamarin Forms
Okay so first of all you need to poll the API in order to receive the data that you need to check. To do this you can implement my PollingTimer.cs class:
using System;
using System.Threading;
using Xamarin.Forms;
namespace CryptoTracker.Helpers
{
/// <summary>
/// This timer is used to poll the middleware for new information.
/// </summary>
public class PollingTimer
{
private readonly TimeSpan timespan;
private readonly Action callback;
private CancellationTokenSource cancellation;
/// <summary>
/// Initializes a new instance of the <see cref="T:CryptoTracker.Helpers.PollingTimer"/> class.
/// </summary>
/// <param name="timespan">The amount of time between each call</param>
/// <param name="callback">The callback procedure.</param>
public PollingTimer(TimeSpan timespan, Action callback)
{
this.timespan = timespan;
this.callback = callback;
this.cancellation = new CancellationTokenSource();
}
/// <summary>
/// Starts the timer.
/// </summary>
public void Start()
{
CancellationTokenSource cts = this.cancellation; // safe copy
Device.StartTimer(this.timespan,
() => {
if (cts.IsCancellationRequested) return false;
this.callback.Invoke();
return true; // or true for periodic behavior
});
}
/// <summary>
/// Stops the timer.
/// </summary>
public void Stop()
{
Interlocked.Exchange(ref this.cancellation, new CancellationTokenSource()).Cancel();
}
}
}
Now that you have added a polling timer to your project, you must now go to the content page that you wish to poll from. Here is the pseudo code for what your content page should look like:
namespace YourApp.Views
{
public class MainPage : ContentPage
{
PollingTimer timer;
public MainPage ()
{
//PUT UI CODE HERE
Content = layout;
//Instantiate Polling timer to call handleaction every 5 seconds
timer = new PollingTimer(TimeSpan.FromSeconds(5), HandleAction);
}
/// <summary>
/// When the page enters the users view, this procedure is called.
/// </summary>
protected override void OnAppearing()
{
base.OnAppearing();
//Handle action and start your timer
HandleAction();
timer.Start();
}
/// <summary>
/// When the page disappears from the users view this procedure is called.
/// </summary>
protected override void OnDisappearing()
{
base.OnDisappearing();
//Stop your timer
timer.Stop(); //Stop the timer
}
/// <summary>
/// Callback for the timer.
/// </summary>
void HandleAction()
{
//Make call to your api to get data
//Compare data with data you currently have
// Do whatever you want.
}
I hope this helps you. Let me know if you need any more help :)
Related Topics
Pick a Number and Name from Contacts List in Android App
Android Studio 2.0 - Pause/White Screen on App First Run
Android: Rotate Image Without Loading It to Memory
How to Wrap Lengthy Text in a Spinner
Read Command Output Inside Su Process
How How to Do Ussd Requests on Android
Android Studio Build Fails with "Task '' Not Found in Root Project 'Myproject'."
Android Gradle Build Error:(9, 0) Gradle Dsl Method Not Found: 'Compile()'
How to Add External Jar Libraries to an Android Project from the Command Line
How to Put an Image in an Alertdialog? Android
Speed Control of Mediaplayer in Android
Get the Last Picture Taken by User
Get Temperature of Battery on Android
Android Device as a Receiver for A2Dp Profile
Fire a Pinch In/Out Command to Android Phone Using Adb
Google Analytics in Android App - Dealing with Multiple Activities
Android/Firebase - Error While Parsing Timestamp in Gcm Event - Null Timestamp