344

I've been trying to start a service when a device boots up on android, but I cannot get it to work. I've looked at a number of links online but none of the code works. Am I forgetting something?

AndroidManifest.xml

<receiver
    android:name=".StartServiceAtBootReceiver"
    android:enabled="true"
    android:exported="false"
    android:label="StartServiceAtBootReceiver" >
    <intent-filter>
        <action android:name="android.intent.action._BOOT_COMPLETED" />
    </intent-filter>
</receiver>

<service
    android:name="com.test.RunService"
    android:enabled="true" />

BroadcastReceiver

public void onReceive(Context context, Intent intent) {
    if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
        Intent serviceLauncher = new Intent(context, RunService.class);
        context.startService(serviceLauncher);
        Log.v("TEST", "Service loaded at start");
    }
}
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
Alex
  • 3,767
  • 5
  • 19
  • 10

15 Answers15

612

The other answers look good, but I thought I'd wrap everything up into one complete answer.

You need the following in your AndroidManifest.xml file:

  1. In your <manifest> element:

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    
  2. In your <application> element (be sure to use a fully-qualified [or relative] class name for your BroadcastReceiver):

    <receiver android:name="com.example.MyBroadcastReceiver">  
        <intent-filter>  
            <action android:name="android.intent.action.BOOT_COMPLETED" />  
        </intent-filter>  
    </receiver>
    

    (you don't need the android:enabled, exported, etc., attributes: the Android defaults are correct)

    In MyBroadcastReceiver.java:

    package com.example;
    
    public class MyBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Intent startServiceIntent = new Intent(context, MyService.class);
            context.startService(startServiceIntent);
        }
    }
    

From the original question:

  • it's not clear if the <receiver> element was in the <application> element
  • it's not clear if the correct fully-qualified (or relative) class name for the BroadcastReceiver was specified
  • there was a typo in the <intent-filter>
Benoit Duffez
  • 11,839
  • 12
  • 77
  • 125
Timo Bruck
  • 7,614
  • 3
  • 17
  • 12
  • 2
    This looks good. I'm gonna use this as a basis, thanks :). No checkmark or upvotes or response sadly :(. Anyone verify this? – Nanne Apr 18 '11 at 18:18
  • 51
    Just a complement: make sure your app is install in internal memory – Bao Le Aug 09 '11 at 02:00
  • Its very simple and perfect, Just i saw the answer once , i wont forgot ever. – Kartihkraj Duraisamy Jan 25 '13 at 06:38
  • 2
    In Android Jellybean 4.2.2 in the tag I had to use the class' relative name instead of the fully-qualified name for the service to start, as noted in http://stackoverflow.com/questions/16671619/android-intentservice-wont-start-on-boot – Piovezan May 21 '13 at 18:38
  • 6
    If the receiver is used for different stuff:
    if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) { Intent serviceIntent = new Intent(context, Service_Location.class); // i.putExtra("KEY1", "Value to be used by the service"); context.startService(serviceIntent); }
    – Gunnar Bernstein Nov 30 '13 at 10:51
  • Can I then stop the receiver from the Activity in the same project? That is, does broadcast receiver start a process, to which service belongs, and also the activities that I can start? That is - if I firstly create service, from an activity, and I can stop it from that activity, and then I reboot and start the same service on startup, can I use the Activity to stop it, like in the first case? – Kobe-Wan Kenobi Jun 29 '14 at 16:05
  • 2
    You should extend https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html instead. It is a Helper for the common pattern of implementing a BroadcastReceiver that receives a device wakeup event and then passes the work off to a Service, while ensuring that the device does not go back to sleep during the transition. This class takes care of creating and managing a partial wake lock for you; you must request the WAKE_LOCK permission to use it. – Damian Oct 29 '14 at 14:47
  • I made an application that contains all the aspects mentioned in your answer. Nevertheless it does not work on my Nexus 5 running Android 5.0.1 although it does work on a Nexus 5 Android 5.0.1 emulator and a Samsung GT-I9100 running Android 4.1.2. What could be wrong with my Nexus? – raptor Feb 14 '15 at 18:56
  • I am having the same problem. Do you mind helping me? Thanks! http://stackoverflow.com/questions/35373525/starting-my-service – Ruchir Baronia Feb 12 '16 at 22:48
  • 1
    @BaoLe this is the default, so you don't need to specify. https://developer.android.com/guide/topics/manifest/manifest-element.html#install – Diego Plentz Oct 25 '17 at 18:11
  • for Oreo, look here: https://stackoverflow.com/questions/44502229/runtime-exception-android-o-with-boot-completed – Andy Weinstein Jan 09 '19 at 09:20
85

As an additional info: BOOT_COMPLETE is sent to applications before external storage is mounted. So if application is installed to external storage it won't receive BOOT_COMPLETE broadcast message.

More details here in section Broadcast Receivers listening for "boot completed"

inazaruk
  • 74,247
  • 24
  • 188
  • 156
  • To prevent the above issue, the developer could set "android:installLocation="internalOnly" in the manifest for an app. Is that a bad idea? For a smartphone app, if 99.9% (my guess) of all users install the app normally, by using internal storage rather than external storage, then it seems the "internalOnly" addition to the manifest would be fine. I would appreciate any thoughts or ideas you have on this. – AJW Jul 14 '18 at 00:41
70

How to start service on device boot(autorun app, etc.)

For first: since version Android 3.1+ you don't receive BOOT_COMPLETE if user never started your app at least once or user "force closed" application. This was done to prevent malware automatically register service. This security hole was closed in newer versions of Android.

Solution:

Create app with activity. When user run it once app can receive BOOT_COMPLETE broadcast message.

For second: BOOT_COMPLETE is sent before external storage is mounted. If app is installed to external storage it won't receive BOOT_COMPLETE broadcast message.

In this case there is two solution:

  1. Install your app to internal storage
  2. Install another small app in internal storage. This app receives BOOT_COMPLETE and run second app on external storage.

If your app already installed in internal storage then code below can help you understand how to start service on device boot.


In Manifest.xml

Permission:

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

Register your BOOT_COMPLETED receiver:

<receiver android:name="org.yourapp.OnBoot">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

Register your service:

<service android:name="org.yourapp.YourCoolService" />

In receiver OnBoot.java:

public class OnBoot extends BroadcastReceiver
{

    @Override
    public void onReceive(Context context, Intent intent) 
    {
        // Create Intent
        Intent serviceIntent = new Intent(context, YourCoolService.class);
        // Start service
        context.startService(serviceIntent);

    }

 }

For HTC you maybe need also add in Manifest this code if device don't catch RECEIVE_BOOT_COMPLETED:

<action android:name="android.intent.action.QUICKBOOT_POWERON" />

Receiver now look like this:

<receiver android:name="org.yourapp.OnBoot">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
</receiver>

How to test BOOT_COMPLETED without restart emulator or real device? It's easy. Try this:

adb -s device-or-emulator-id shell am broadcast -a android.intent.action.BOOT_COMPLETED

How to get device id? Get list of connected devices with id's:

adb devices

adb in ADT by default you can find in:

adt-installation-dir/sdk/platform-tools

Enjoy! )

icebat
  • 4,696
  • 4
  • 22
  • 36
user3439968
  • 3,418
  • 1
  • 18
  • 15
34

Along with

<action android:name="android.intent.action.BOOT_COMPLETED" />  

also use,

<action android:name="android.intent.action.QUICKBOOT_POWERON" />

HTC devices dont seem to catch BOOT_COMPLETED

Tony
  • 2,242
  • 22
  • 33
  • Need to add anything similar in permissions for HTC devices ? – Nanda Jun 16 '15 at 19:36
  • 2
    This could be useful in some circumstances, but I understand the HTC Fast Boot is a form of hibernation where system state is saved to the filesystem, and the `android.intent.action.QUICKBOOT_POWERON` is only sent when restoring from fast boot. This means it isn't necessary to do things like resetting alarms when recovering from Fast Boot as they are preserved. Therefore it would only be necessary to use `` if you want to do something when the user thinks the device has booted. – HexAndBugs Jul 14 '15 at 09:33
  • 2
    From a app developer's perspective, we should never use this, if the behaviour exists only on HTC devices. Because, BOOT_COMPLETED is, as per the documentation, will always be sent when the device turns ON. Some other manufacturer could come up with another method of fast booting and we would end up messing our code with each one's specifications. – C-- Aug 01 '15 at 12:55
  • @HexAndBugs Were you able to confirm that Fast Boot is a form of hibernation where system state is saved to the filesystem? I want to be able to reset alarms that are used for future Notifications after a Fast Boot if system state is not saved...please advise. – AJW Jul 14 '18 at 00:48
20

note that at the beginning of the question, there is a typo mistake:

<action android:name="android.intent.action._BOOT_COMPLETED"/>

instead of :

<action android:name="android.intent.action.BOOT_COMPLETED"/>

one small "_" and all this trouble :)

Evgeny Erlihman
  • 458
  • 4
  • 12
13

I think your manifest needs to add:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
RickNotFred
  • 3,381
  • 2
  • 24
  • 26
  • I am having the same problem. Do you mind helping me? Thanks! http://stackoverflow.com/questions/35373525/starting-my-service – Ruchir Baronia Feb 12 '16 at 22:48
13

I found out just now that it might be because of Fast Boot option in Settings > Power

When I have this option off, my application receives a this broadcast but not otherwise.

By the way, I have Android 2.3.3 on HTC Incredible S.

Hope it helps.

Omer Akhter
  • 265
  • 1
  • 4
  • 11
7

After trying all of mentioned answers and tricks, I finally find why the code is not work in my phone. Some Android phones like "Huawei Honor 3C Android 4.2.2" have a Statup Manager menu in their settings and your app must be checked in the list. :)

Amir
  • 652
  • 9
  • 19
5

I have an additional <category>-tag, don't know if that makes any difference.

<receiver android:name="BootIntentReceiver">  
        <intent-filter>  
            <action android:name="android.intent.action.BOOT_COMPLETED" />  
            <category android:name="android.intent.category.HOME" />  
        </intent-filter>  
</receiver>

Have you tried ommiting the if-clause "android.intent.action.BOOT_COMPLETED".equals(intent.getAction(), as the receiver probably only receives that intent anyway?

Nick
  • 3,504
  • 2
  • 39
  • 78
  • tried this and it didn't work btw i forgot to mention i also have the – Alex May 06 '10 at 21:18
  • 2
    just in case: adding android.intent.category.HOME to any tag in the AndroidManifest will cause the Samsung Galaxy Tab to run the app in compatibility mode, even after using the hack to turn compatibility mode off. not sure if this is the same for other tabs. i recommend not setting the HOME category at all. it's unnecessary. – moonlightcheese Mar 10 '11 at 23:31
5

This is what I did

1. I made the Receiver class

public class BootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //whatever you want to do on boot
       Intent serviceIntent = new Intent(context, YourService.class);
       context.startService(serviceIntent);
    }
}

2.in the manifest

<manifest...>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <application...>
        <receiver android:name=".BootReceiver" android:enabled="true" android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    ...

3.and after ALL you NEED to "set" the receiver in your MainActivity, it may be inside the onCreate

...
 final ComponentName onBootReceiver = new ComponentName(getApplication().getPackageName(), BootReceiver.class.getName());
        if(getPackageManager().getComponentEnabledSetting(onBootReceiver) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED)
        getPackageManager().setComponentEnabledSetting(onBootReceiver,PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP);
...

the final steap I have learned from ApiDemos

San Juan
  • 107
  • 1
  • 10
  • you should check for the incoming intent on your `onReceive` method (`BOOT_COMPLETED`), otherwise, your app will be called from suspicious apps installed on your device. – blueware Dec 12 '20 at 08:34
4

Refer This Link http://khurramitdeveloper.blogspot.in/2013/06/start-activity-or-service-on-boot.html Step by Step procedure to use boot on Service

Jaichander
  • 812
  • 2
  • 15
  • 24
2

If you're using Android Studio and you're very fond of auto-complete then I must inform you, I'm using Android Studio v 1.1.0 and I used auto-complete for the following permission

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

And Android Studio Auto-completedRECEIVE_BOOT_COMPLETED all in lower-case like receive_boot_completed and I kept pulling my hair out because I'd already ticked out my checklist for things to do to start service at boot. I just confirmed again

Android Studio DOES auto-complete this permission in lower-case.

meowmeowbeans
  • 687
  • 7
  • 14
2

As @Damian commented, all the answers in this thread are doing it wrong. Doing it manually like this runs the risk of your Service being stopped in the middle from the device going to sleep. You need to obtain a wake lock first. 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 permssion to your mainfest:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
phreakhead
  • 14,721
  • 5
  • 39
  • 40
  • Little question i have a doubt. If my _service_ is a **Service** and not **IntentService** i can not use this way, because **onHandleIntend** method can not be _override_ in simple **Service**? – paolo2988 Aug 19 '15 at 15:34
  • I am having the same problem. Do you mind helping me? Thanks! http://stackoverflow.com/questions/35373525/starting-my-service – Ruchir Baronia Feb 12 '16 at 22:49
  • Maybe use `onNewIntent()`? Or you could look at the source for IntentService and see what you need to do for your Service to make it match... – phreakhead Mar 04 '16 at 21:29
1

In fact,I get into this trouble not long ago,and it's really really easy to fix,you actually do nothing wrong if you setup the "android.intent.action.BOOT_COMPLETED" permission and intent-filter.

Be attention that if you On Android 4.X,you have to run the broadcast listener before you start service on boot,that means,you have to add an activity first,once your broadcast receiver running,your app should function as you expected,however,on Android 4.X,I haven't found a way to start the service on boot without any activity,I think google did that for security reasons.

David Hx
  • 125
  • 1
  • 2
  • 12
0

I faced with this problem if i leave the empty constructor in the receiver class. After the removing the empty contsructor onRreceive methos started working fine.

redrom
  • 11,502
  • 31
  • 157
  • 264