75

I created a service and want to run this service always until my phone restarts or force closed. The service should run in background.

Sample code of created service and start services:

Start the service:

Intent service = new Intent(getApplicationContext(), MyService.class);
getApplicationContext().startService(service);

The service:

public class MyService extends Service {

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO do something useful
        HFLAG = true;
        //smsHandler.sendEmptyMessageDelayed(DISPLAY_DATA, 1000);
        return Service.START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO for communication return IBinder implementation
        return null;
    }
}

Manifest declaration:

<service
    android:name=".MyService"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
</service>

Is it possible to run this service always as when the application pauses and anything else. After some time my application goes pause and the services also go pause or stop. So how can I run this service in background and always.

Chris Schiffhauer
  • 17,102
  • 15
  • 79
  • 88
  • 1
    Not possible without making it a part of the system image. Android may kill your application entirely in some cases. When your application get killed, its services won't be alive. – StarPinkER Apr 02 '13 at 08:09
  • 2
    Thanks for reply,How can I make my application as a part of the system image. – Ashekur Rahman Molla Asik Apr 02 '13 at 08:11
  • You need to modify the firmware. If this is acceptable, I can write an answer. – StarPinkER Apr 02 '13 at 08:13
  • you can do this.. like for incomming call check your service is running or not if not then start it again... same way use media scanner complate, boot complate, incomming sms... etc. you have to check each & every time your service is running or not just like Watsup Massage service. but i am not recomodate you to do this. for more detail check this : http://stackoverflow.com/a/6091362/1168654 and http://stackoverflow.com/a/4353653/1168654 and – Dhaval Parmar Apr 02 '13 at 08:26

9 Answers9

95

"Is it possible to run this service always as when the application pause and anything else?"

Yes.

  1. In the service onStartCommand method return START_STICKY.

    public int onStartCommand(Intent intent, int flags, int startId) {
            return START_STICKY;
    }
    
  2. Start the service in the background using startService(MyService) so that it always stays active regardless of the number of bound clients.

    Intent intent = new Intent(this, PowerMeterService.class);
    startService(intent);
    
  3. Create the binder.

    public class MyBinder extends Binder {
            public MyService getService() {
                    return MyService.this;
            }
    }
    
  4. Define a service connection.

    private ServiceConnection m_serviceConnection = new ServiceConnection() {
            public void onServiceConnected(ComponentName className, IBinder service) {
                    m_service = ((MyService.MyBinder)service).getService();
            }
    
            public void onServiceDisconnected(ComponentName className) {
                    m_service = null;
            }
    };
    
  5. Bind to the service using bindService.

            Intent intent = new Intent(this, MyService.class);
            bindService(intent, m_serviceConnection, BIND_AUTO_CREATE);
    
  6. For your service you may want a notification to launch the appropriate activity once it has been closed.

    private void addNotification() {
            // create the notification
            Notification.Builder m_notificationBuilder = new Notification.Builder(this)
                    .setContentTitle(getText(R.string.service_name))
                    .setContentText(getResources().getText(R.string.service_status_monitor))
                    .setSmallIcon(R.drawable.notification_small_icon);
    
            // create the pending intent and add to the notification
            Intent intent = new Intent(this, MyService.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
            m_notificationBuilder.setContentIntent(pendingIntent);
    
            // send the notification
            m_notificationManager.notify(NOTIFICATION_ID, m_notificationBuilder.build());
    }
    
  7. You need to modify the manifest to launch the activity in single top mode.

              android:launchMode="singleTop"
    
  8. Note that if the system needs the resources and your service is not very active it may be killed. If this is unacceptable bring the service to the foreground using startForeground.

            startForeground(NOTIFICATION_ID, m_notificationBuilder.build());
    
Stephen Donecker
  • 2,361
  • 18
  • 8
  • After sometime this service automatically go to sleep by using this. – Ashekur Rahman Molla Asik Apr 03 '13 at 07:09
  • What do you mean "go to sleep by using this"? Yes the service may be killed by the system on occasion but it will be automatically restarted when using START_STICKY. – Stephen Donecker Apr 08 '13 at 21:51
  • 1
    A very good answer - it worked perfectly. Many other answers to similar questions were partial whilst this one is complete. – Andrew Alcock Nov 13 '13 at 13:27
  • 24
    Could you elaborate on #8? Where is this executed? And about #5, is this executed in the same place as where one starts the service? And do I understand you correctly that you use notifications to keep the service alive at all times? – Tom Jan 21 '14 at 09:57
  • 2
    @Stephen Donecker why do I have to bind it? – Silvia H Aug 12 '15 at 16:30
  • is activity lifecycle (on same process) orthogonal (not dependent) with service lifecycle ? – ransh May 17 '16 at 21:11
  • 2
    @SilviaHisham you don't. Binding is typically done when the service needs to communicate with activities – Tim Aug 25 '16 at 08:32
  • Step 4 : `m_service` is accessed within inner class, needs to be declared `final`. But if you'll declare it final, it cannot be modified anywhere and eventually it will show **compile time error** in `onServiceConnected()` method. – Apurva Sep 20 '16 at 07:08
  • Can anyone explain to me where steps 4, 5, 6 and 8 happen? And do I understand it correctly that step 3 is within the `Service class`? – Spurious Dec 08 '16 at 14:34
  • PowerMeterService?!?! – David Apr 19 '17 at 11:15
  • # 1 is the only true in the list. #2 is an obvious process to start a service in Android. # 3, 4, 5 are necessary only if you want get the instance of the service.# 6 and, 8 if you want your notification to be sticky, i.e, it requires user consent to be removed. I'm not sure about # 7 – mr5 Jul 26 '17 at 16:52
  • This is confusing rather a solution. From what I read, if you bind a service, it will be stopped when activity dies. Why there is a mention of binding in the answer when the question says "always running"? – Talha Jul 27 '17 at 09:36
  • Does android:process=”: remote will work if background data is OFF or Battery Saver is ON? – Rajesh N Sep 30 '17 at 07:13
  • on which thread the service is running after was restarted(START_STICKY)? – Pavel Poley Apr 05 '18 at 11:32
  • Hi, I am also stuck with it. can anyone of you share his code? I have tried but not get success. In my service, I am fetching current location and sending to firebase database. but when I killed or minimize my app, service is getting killed. – Rajneesh Shukla Jun 26 '19 at 11:30
  • What should be the secret of your code? The foreground service, the bound service? – testing Mar 19 '20 at 16:54
8

In order to start a service in its own process, you must specify the following in the xml declaration.

<service
  android:name="WordService"
  android:process=":my_process" 
  android:icon="@drawable/icon"
  android:label="@string/service_name"
  >
</service> 

Here you can find a good tutorial that was really useful to me

http://www.vogella.com/articles/AndroidServices/article.html

Hope this helps

Chris Schiffhauer
  • 17,102
  • 15
  • 79
  • 88
Juan
  • 229
  • 2
  • 6
  • 20
3

A simple solution is to restart the service when the system stops it.

I found this very simple implementation of this method:

How to make android service unstoppable

Chris Schiffhauer
  • 17,102
  • 15
  • 79
  • 88
Alecs
  • 2,900
  • 1
  • 22
  • 25
  • How does this work in Android O which doesn't allow a broadcast receiver in the background the start a service bro? – famfamfam Jan 15 '20 at 08:12
  • Not worked when setting targetSdkVersion to 30. case1: Keep the application in the background for more than 3 minutes: Service gets killed. case2: On app killed: Service gets killed – Shanki Bansal Aug 12 '21 at 07:17
3

If you already have a service and want it to work all the time, you need to add 2 things:

  1. in the service itself:

    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }
    
  2. In the manifest:

    android:launchMode="singleTop"
    

No need to add bind unless you need it in the service.

Chris Schiffhauer
  • 17,102
  • 15
  • 79
  • 88
Gilad Levinson
  • 234
  • 2
  • 12
  • Not worked when setting targetSdkVersion to 30. case1: Keep the application in the background for more than 1 minute: Service gets killed. case2: On app killed: Service gets killed – Shanki Bansal Aug 12 '21 at 07:27
2

You can implement startForeground for the service and even if it dies you can restart it by using START_STICKY on startCommand(). Not sure though this is the right implementation.

Baris Demiray
  • 1,539
  • 24
  • 35
Srikanth Roopa
  • 1,782
  • 2
  • 13
  • 19
0

I found a simple and clear way of keeping the Service running always.

This guy has explained it so clearly and have used a good algorithm. His approach is to send a Broadcast when the service is about to get killed and then use it to restart the service.

You should check it out: http://fabcirablog.weebly.com/blog/creating-a-never-ending-background-service-in-android

Hammad Nasir
  • 2,889
  • 7
  • 52
  • 133
  • 4
    How does this work in Android O which doesn't allow a broadcast receiver in the background the start a service? – Michael Sep 16 '17 at 22:24
0

You don't require broadcast receiver. If one would take some pain copy one of the api(serviceconnection) from above example by Stephen Donecker and paste it in google you would get this, https://www.concretepage.com/android/android-local-bound-service-example-with-binder-and-serviceconnection

Chirag Dave
  • 786
  • 6
  • 5
-1

Add this in manifest.

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

Add a service class.

public class YourServiceName extends Service {


    @Override
    public void onCreate() {
        super.onCreate();

      // Timer task makes your service will repeat after every 20 Sec.
       TimerTask doAsynchronousTask = new TimerTask() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                    public void run() {
                       // Add your code here.

                     }

               });
            }
        };
  //Starts after 20 sec and will repeat on every 20 sec of time interval.
        timer.schedule(doAsynchronousTask, 20000,20000);  // 20 sec timer 
                              (enter your own time)
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO do something useful

      return START_STICKY;
    }

}
Avinash Shinde
  • 385
  • 6
  • 14
-1

I had overcome this issue, and my sample code is as follows.

Add the below line in your Main Activity, here BackGroundClass is the service class.You can create this class in New -> JavaClass (In this class, add the process (tasks) in which you needs to occur at background). For Convenience, first denote them with notification ringtone as background process.

 startService(new Intent(this, BackGroundClass .class));

In the BackGroundClass, just include my codings and you may see the result.

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.widget.Toast;

public class BackgroundService  extends Service {
    private MediaPlayer player;
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
     player = MediaPlayer.create(this,Settings.System.DEFAULT_RINGTONE_URI);
        player.setLooping(true);
         player.start();
        return START_STICKY;
    }
 @Override
    public void onDestroy() {
        super.onDestroy();
         player.stop();
    }
}

And in AndroidManifest.xml, try to add this.

<service android:name=".BackgroundService"/>

Run the program, just open the application, you may find the notification alert at the background. Even, you may exit the application but still you might have hear the ringtone alert unless and until if you switched off the application or Uninstall the application. This denotes that the notification alert is at the background process. Like this you may add some process for background.

Kind Attention: Please, Don't verify with TOAST as it will run only once even though it was at background process.

Hope it will helps...!!