Android Starting Service at Boot Time , How to restart service class after device Reboot?
Asked Answered
L

9

116

I need to start a service at boot time. I searched a lot. They are talking about Broadcastreceiver. As I am new to android development, I didn't get a clear picture about services on Android. Please provide some source code.

Lambdoid answered 30/12, 2010 at 12:52 Comment(3)
@user244540: Please do not "start a service at boot time" with the intention of it running forever, unless it is continuously delivering value (e.g., a VOIP client). In those cases, use startForeground() in your service. Otherwise, Android and its users will kill off your service as being a waste of space, and you will get some unpleasant comments in the Android Market. Most situations where you think you want a service to start at boot time, you are better served using AlarmManager so your service can run periodically rather than continuously.Mendelism
@CommonsWare: Good point. However note, that to start periodic runs by AlarmManager after restart, you need to follow very similar steps (the difference being in the contents of onReceive method)Fussell
@CommonsWare: Very good comment, I stumbled across this question and your hint exactly fits my situation. If it was an answer I would have voted it up :-)Stator
E
97

Create a BroadcastReceiver and register it to receive ACTION_BOOT_COMPLETED. You also need RECEIVE_BOOT_COMPLETED permission.

Read: Listening For and Broadcasting Global Messages, and Setting Alarms

Effluvium answered 30/12, 2010 at 13:3 Comment(5)
what about wake lock? while service is being started the device may decide to go asleep...Decree
Do i need to boot my mobile at least once to start a service??Cimbalom
@MarianPaździoch is right; you need a wake lock. See my answer below: https://mcmap.net/q/187524/-android-starting-service-at-boot-time-how-to-restart-service-class-after-device-rebootPen
@Cimbalom on boot, yes. See commonsware.com/blog/2011/07/05/boot-completed-regression.htmlClosemouthed
Your latest URL is outdatedVenator
I
197

Your receiver:

public class MyReceiver extends BroadcastReceiver {   

    @Override
    public void onReceive(Context context, Intent intent) {

     Intent myIntent = new Intent(context, YourService.class);
     context.startService(myIntent);

    }
}

Your AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.broadcast.receiver.example"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">

        <activity android:name=".BR_Example"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    <!-- Declaring broadcast receiver for BOOT_COMPLETED event. -->
        <receiver android:name=".MyReceiver" android:enabled="true" android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

    </application>

    <!-- Adding the permission -->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

</manifest>
Induline answered 30/12, 2010 at 12:55 Comment(7)
The link to the article is dead but the sample code is all you need anyway, so +1 :)Muldoon
Actually, it needs little improve, you must use wakelock in receiver, otherwise there is a little chance your service is not going to start.Induline
Do i need to boot my mobile at least once to make this work??Cimbalom
Nope, but you must run the application at least one since android 3.0Induline
Does this work if app is force closed from settings? Will the app still wakeup?Penland
How did this work without the service being declared in the manifest?Cheryl
for some reason, this isn't working for me. my service isn't startingKovacs
E
97

Create a BroadcastReceiver and register it to receive ACTION_BOOT_COMPLETED. You also need RECEIVE_BOOT_COMPLETED permission.

Read: Listening For and Broadcasting Global Messages, and Setting Alarms

Effluvium answered 30/12, 2010 at 13:3 Comment(5)
what about wake lock? while service is being started the device may decide to go asleep...Decree
Do i need to boot my mobile at least once to start a service??Cimbalom
@MarianPaździoch is right; you need a wake lock. See my answer below: https://mcmap.net/q/187524/-android-starting-service-at-boot-time-how-to-restart-service-class-after-device-rebootPen
@Cimbalom on boot, yes. See commonsware.com/blog/2011/07/05/boot-completed-regression.htmlClosemouthed
Your latest URL is outdatedVenator
H
33

It's possible to register your own application service for starting automatically when the device has been booted. You need this, for example, when you want to receive push events from a http server and want to inform the user as soon a new event occurs. The user doesn't have to start the activity manually before the service get started...

It's quite simple. First give your app the permission RECEIVE_BOOT_COMPLETED. Next you need to register a BroadcastReveiver. We call it BootCompletedIntentReceiver.

Your Manifest.xml should now look like this:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.jjoe64">
 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
 <application>
  <receiver android:name=".BootCompletedIntentReceiver">
   <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
   </intent-filter>
  </receiver>
  <service android:name=".BackgroundService"/>
 </application>
</manifest>

As the last step you have to implement the Receiver. This receiver just starts your background service.

package com.jjoe64;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

import com.jjoe64.BackgroundService;

public class BootCompletedIntentReceiver extends BroadcastReceiver {
 @Override
 public void onReceive(Context context, Intent intent) {
  if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
   Intent pushIntent = new Intent(context, BackgroundService.class);
   context.startService(pushIntent);
  }
 }
}

From http://www.jjoe64.com/2011/06/autostart-service-on-device-boot.html

Haphazard answered 22/6, 2011 at 13:36 Comment(7)
Same as the above but really simple and fast, use this one if u come by this post.Lancelot
The only difference is that this declares the Service on the Manifest, which is correct.Hegira
It is not only correct to declare your service in the manifest, it is required. Same as with activitiesClosemouthed
Where is the Main Activity!? It is not correct to make app without activities or android.intent.category.LAUNCHER!Diabolize
@L'Esperanza for sure, you can have apps that have no visible activities!Haphazard
@jjoe64, if there are no visible activity receiver doesn't work. And service can only be started by another app.Diabolize
@L'Esperanza no you're wrong. App can be started without an activity :)Arabele
P
15

Most the solutions posted here are missing an important piece: doing it without a wake lock runs the risk of your Service getting killed before it is finished processing. Saw this solution in another thread, answering here as well.

Since WakefulBroadcastReceiver is deprecated in api 26 it is recommended for API Levels below 26

You need to obtain a wake lock . Luckily, the Support library gives us a class to do this:

public class SimpleWakefulReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // This is the Intent to deliver to our service.
        Intent service = new Intent(context, SimpleWakefulService.class);

        // Start the service, keeping the device awake while it is launching.
        Log.i("SimpleWakefulReceiver", "Starting service @ " + SystemClock.elapsedRealtime());
        startWakefulService(context, service);
    }
}

then, in your Service, make sure to release the wake lock:

    @Override
    protected void onHandleIntent(Intent intent) {
        // At this point SimpleWakefulReceiver is still holding a wake lock
        // for us.  We can do whatever we need to here and then tell it that
        // it can release the wakelock.

...
        Log.i("SimpleWakefulReceiver", "Completed service @ " + SystemClock.elapsedRealtime());
        SimpleWakefulReceiver.completeWakefulIntent(intent);
    }

Don't forget to add the WAKE_LOCK permission and register your receiver in the manifest:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

...

<service android:name=".SimpleWakefulReceiver">
    <intent-filter>
        <action android:name="com.example.SimpleWakefulReceiver"/>
    </intent-filter>
</service>
Pen answered 21/6, 2015 at 22:58 Comment(2)
In the manifest file, SimpleWakefulReceiver is not a service.Lanark
WakefulBroadcastReceiver is deprecatedEnviron
B
5

you should register for BOOT_COMPLETE as well as REBOOT

<receiver android:name=".Services.BootComplete">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <action android:name="android.intent.action.REBOOT"/>
        </intent-filter>
    </receiver> 
Barcarole answered 22/12, 2016 at 7:15 Comment(1)
Literature says that 'android.intent.action.REBOOT' can only be used by privileged app/code. What advantage is this otherwise?Hedwighedwiga
P
1

Also register your created service in the Manifest and uses-permission as

<application ...>
   <service android:name=".MyBroadcastReceiver">
        <intent-filter>
            <action android:name="com.example.MyBroadcastReciver"/>
        </intent-filter>
   </service>
</application>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

and then in braod cast Reciever call your service

public class MyBroadcastReceiver extends BroadcastReceiver 
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        Intent myIntent = new Intent(context, MyService.class);
        context.startService(myIntent);
    }
}
Pattison answered 6/6, 2013 at 6:8 Comment(6)
Why the Intent Filter inside the service?Hegira
because when the boot completed then the MyService will be calledPattison
In that case your service class will extend service and broadcast receiver. Am I right?Hegira
The class will extend Service class.Pattison
There's something wrong here. The service is supposed to be called from the Broadcast Receiver. But you're saying that your service is the broadcast receiver and after that you tell me that the service class doesn't extend Broadcast Receiver. Thus, it won't receive the Boot Completed Broadcast. What are you overriding when you declare the onReceive method?Hegira
Yes you are right the service will be called from the broadcast Receiver, and the receiver will be called at boot time.Pattison
R
1

To Restart service in Android O or more ie OS >28 Use this code KOTLIN VERSION 1) Add permission in manifest

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

2) Create a Class and extend it with BroadcastReceiver

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
import androidx.core.content.ContextCompat



class BootCompletedReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, arg1: Intent?) {
        Log.d("BootCompletedReceiver", "starting service...")
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            ContextCompat.startForegroundService(context, Intent(context, YourServiceClass::class.java))
        } else {
            context.startService(Intent(context, YourServiceClass::class.java))
        }
    }
}

3) Declare in Manifest file like this under application tag

<receiver android:name=".utils.BootCompletedReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
        </intent-filter>
    </receiver>
Rheo answered 17/3, 2020 at 7:16 Comment(0)
B
0

First register a receiver in your manifest.xml file:

    <receiver android:name="com.mileagelog.service.Broadcast_PowerUp" >
        <intent-filter>
            <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
            <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
        </intent-filter>
    </receiver>

and then write a broadcast for this receiver like:

public class Broadcast_PowerUp extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();

    if (action.equals(Intent.ACTION_POWER_CONNECTED)) {
        Toast.makeText(context, "Service_PowerUp Started",
                Toast.LENGTH_LONG).show();


    } else if (action.equals(Intent.ACTION_POWER_DISCONNECTED)) {



        Toast.makeText(context, "Service_PowerUp Stoped", Toast.LENGTH_LONG)
        .show();
    }
  }
}
Bouchard answered 3/10, 2013 at 12:3 Comment(0)
D
-1

Pls check JobScheduler for apis above 26

WakeLock was the best option for this but it is deprecated in api level 26 Pls check this link if you consider api levels above 26
https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html#startWakefulService(android.content.Context,%20android.content.Intent)

It says

As of Android O, background check restrictions make this class no longer generally useful. (It is generally not safe to start a service from the receipt of a broadcast, because you don't have any guarantees that your app is in the foreground at this point and thus allowed to do so.) Instead, developers should use android.app.job.JobScheduler to schedule a job, and this does not require that the app hold a wake lock while doing so (the system will take care of holding a wake lock for the job).

so as it says cosider JobScheduler
https://developer.android.com/reference/android/app/job/JobScheduler

if it is to do something than to start and to keep it you can receive the broadcast ACTION_BOOT_COMPLETED

If it isn't about foreground pls check if an Accessibility service could do

another option is to start an activity from broadcast receiver and finish it after starting the service within onCreate() , since newer android versions doesnot allows starting services from receivers

Drice answered 20/11, 2018 at 19:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.