How to Keep My Android Service Running When the Screen Is Turned Off

Keep a Service running even when phone is asleep?

Note: This post has been updated to include the JobScheduler API of the Android Lollipop release. The following is still a viable way, but can be considered deprecated if you're targeting Android Lollipop and beyond. See the second half for the JobScheduler alternative.

One way to do recurrent tasks is this:

  • Create a class AlarmReceiver

    public class AlarmReceiver extends BroadcastReceiver 
    {
    @Override
    public void onReceive(Context context, Intent intent)
    {
    Intent myService = new Intent(context, YourService.class);
    context.startService(myService);
    }
    }

    with YourService being your service ;-)

If you require a wake lock for your Task, it is advisable to extend from WakefulBroadcastReceiver. Don't forget to add the WAKE_LOCK permission in your Manifest in this case!

  • Create a Pending Intent

To start your recurrent polling, execute this code in your activity:

Intent myAlarm = new Intent(getApplicationContext(), AlarmReceiver.class);
//myAlarm.putExtra("project_id", project_id); //Put Extra if needed
PendingIntent recurringAlarm = PendingIntent.getBroadcast(getApplicationContext(), 0, myAlarm, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarms = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
Calendar updateTime = Calendar.getInstance();
//updateTime.setWhatever(0); //set time to start first occurence of alarm
alarms.setInexactRepeating(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(), AlarmManager.INTERVAL_DAY, recurringAlarm); //you can modify the interval of course

This code sets up an alarm and a canceable pendingIntent. The alarmManager gets the job to repeat the recurringAlarm every day (third argument), but inexact so the CPU does wake up approximately after the interval but not exactly (It lets the OS choose the optimal time, which reduces battery drain). The first time the alarm (and thus the service) is started will be the time you choose to be updateTime.

  • last but not least: here is how to kill the recurring alarm

    Intent myAlarm = new Intent(getApplicationContext(), AlarmReceiver.class);
    //myAlarm.putExtra("project_id",project_id); //put the SAME extras
    PendingIntent recurringAlarm = PendingIntent.getBroadcast(getApplicationContext(), 0, myAlarm, PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager alarms = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    alarms.cancel(recurringAlarm);

This code creates a copy of your (probably) existing alarm and tells the alarmManager to cancel all alarms of that kind.

  • of course there is also something to do in the Manifest:

include these two lines

  < receiver android:name=".AlarmReceiver"></receiver>
< service android:name=".YourService"></service>

inside the < application>-tag. Without it, the system does not accept the start of recurrent alarm of a service.


Starting with the Android Lollipop release, there's a new way of solving this task elegantly.
This also makes it easier to only perform an action if certain criteria such as network state are met.

// wrap your stuff in a componentName
ComponentName mServiceComponent = new ComponentName(context, MyJobService.class);
// set up conditions for the job
JobInfo task = JobInfo.Builder(mJobId, mServiceComponent)
.setPeriodic(mIntervalMillis)
.setRequiresCharging(true) // default is "false"
.setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED) // Parameter may be "ANY", "NONE" (=default) or "UNMETERED"
.build();
// inform the system of the job
JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(task);

You may also provide a deadline with setOverrideDeadline(maxExecutionDelayMillis).

To get rid of such a task, just call jobScheduler.cancel(mJobId); or jobScheduler.cancelAll();.

How to keep Android service alive when screen off and home pressed?

Whenever an app runs in the background, it consumes some of the device's limited resources, like RAM. This can result in an impaired user experience, especially if the user is using a resource-intensive app, such as playing a game or watching video. To improve the user experience, Android 8.0 (API level 26) imposes limitations on what apps can do while running in the background. This document describes the changes to the operating system, and how you can update your app to work well under the new limitations.
https://developer.android.com/about/versions/oreo/background

Background service stops when phone goes in idle state

So there were some ways for a service not to be killed when device goes in sleep mode.
I started my service as a foreground service attached with the notification. I don't say that its the better approach for a long term service. But of-course this solution is open for more optimization. This solution doesn't get the service go in pause state while in sleep mode.

Following is the whole service code:

public class TimerService extends Service {
private ScheduledExecutorService scheduleTaskExecutor;
private Context context;
@Override
public IBinder onBind(Intent intent) {
Logger.LogI(TAG, "Service binding");
return null;
}

@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
setNotification();
if (scheduleTaskExecutor == null) {
scheduleTaskExecutor = Executors.newScheduledThreadPool(1);
scheduleTaskExecutor.scheduleAtFixedRate(new mainTask(), 0, 1, TimeUnit.SECONDS);
}
return Service.START_STICKY;
}

public void setNotification() {
PendingIntent contentIntent;
contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, Main_Activity.class), 0);

NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setColor(this.getResources().getColor(R.color.action_bar_color))
.setContentTitle("MainActivity")
.setOngoing(true)
.setAutoCancel(false)
.setContentText("MyApp");
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());

Notification notification = mBuilder.build();
startForeground(NOTIFICATION_ID, notification); //NOTIFICATION_ID is a random integer value which has to be unique in an app
}
}
private class mainTask implements Runnable {

public void run() {
// 1 Second Timer
}
}

Helpful Links:

Run a service in the background forever..? Android

How to run background service after every 5 sec not working in android 5.1?

How to run a method every X seconds

How to make service run even in sleep mode?

part-1 persistent foreGround android service that starts by UI, works at sleep mode too, also starts at phone restart

part-2 persistent foreGround android service that starts by UI, works at sleep mode too, also starts at phone restart

Android - implementing startForeground for a service?

does service or handler go to sleep too when device's lcd goes off?

Your application will be paused after a while if device screen is locked. The CPU will sleep until user wakes the device, so, your Service won't do anything while device sleeps.

If you want to perform some action even when the screen is turned off, you can acquire a WakeLock: http://developer.android.com/reference/android/os/PowerManager.WakeLock.html
But be careful, using the WakeLock too much will drain battery fast.

Also, another class that may be useful for you is WakefulBroadcastReceiver: https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html

What it does is, it receives some Intent and acquires a WakeLock for you so that you can finish your work in a Service. Without this you have no guarantee that device will finish the work and not go to sleep.

Why foreground service stops when screen is off on Android Oreo?

You can solve your problem with the help of this repository. This repository is for location but I am sure it will help you a lot.



Related Topics



Leave a reply



Submit