131

From everything I've seen on Stack Exchange and elsewhere, I have everything set up correctly to start an IntentService when Android OS boots. Unfortunately it is not starting on boot, and I'm not getting any errors. Maybe the experts can help...

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.phx.batterylogger"
  android:versionCode="1"
  android:versionName="1.0"
  android:installLocation="internalOnly">

<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.BATTERY_STATS" />

<application android:icon="@drawable/icon" android:label="@string/app_name">
    <service android:name=".BatteryLogger"/>
    <receiver android:name=".StartupIntentReceiver">  
        <intent-filter>  
            <action android:name="android.intent.action.BOOT_COMPLETED" />  
        </intent-filter>  
    </receiver>
</application>

</manifest>

BroadcastReceiver for Startup:

package com.phx.batterylogger;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class StartupIntentReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent serviceIntent = new Intent(context, BatteryLogger.class);
        context.startService(serviceIntent);
    }
}

UPDATE: I tried just about all of the suggestions below, and I added logging such as Log.v("BatteryLogger", "Got to onReceive, about to start service"); to the onReceive handler of the StartupIntentReceiver, and nothing is ever logged. So it isn't even making it to the BroadcastReceiver.

I think I'm deploying the APK and testing correctly, just running Debug in Eclipse and the console says it successfully installs it to my Xoom tablet at \BatteryLogger\bin\BatteryLogger.apk. Then to test, I reboot the tablet and then look at the logs in DDMS and check the Running Services in the OS settings. Does this all sound correct, or am I missing something? Again, any help is much appreciated.

Gady
  • 4,935
  • 8
  • 38
  • 48
  • 1
    what problem you are getting, aren't you getting any UI..? – Lalit Poptani Oct 07 '11 at 16:55
  • 1
    The service just never starts, that's the problem. – Gady Oct 07 '11 at 16:59
  • how you come to know that your service is not getting started, have you printed the Logs or anything like that..? – Lalit Poptani Oct 07 '11 at 17:02
  • 1
    You don't need logs to see its not running. The Android OS exposes running services. However, it would be wise to use logging to see if an error is occurring. I would venture a guess that it happens before context.startService() if an error is occurring. – Tony Oct 07 '11 at 17:08
  • 1
    I added `Log.v("BatteryLogger", "Got to onReceive, about to start service");` to the onReceive handler, and it never shows up in the logs. So the listener is failing(?) – Gady Oct 07 '11 at 17:16
  • Why you are writing broadcast receiver. You can directly start your service on receive of BOOT_COMPLETED intent. Just a thought. – Vivek Oct 07 '11 at 17:19
  • @HellBoy Can you elaborate on this a bit? – Gady Oct 07 '11 at 17:28
  • I added an update describing my deploy/testing methodology – Gady Oct 07 '11 at 20:26
  • Please test my complete example is a working demo for you, it will work for sure... – Lalit Poptani Oct 08 '11 at 01:39
  • https://stackoverflow.com/questions/2784441/trying-to-start-a-service-on-boot-on-android?answertab=active#tab-top – San Juan Oct 24 '17 at 21:20

6 Answers6

334

Well here is a complete example of an AutoStart Application

AndroidManifest file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="pack.saltriver" android:versionCode="1" android:versionName="1.0">

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

    <application android:icon="@drawable/icon" android:label="@string/app_name">

        <receiver android:name=".autostart">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <activity android:name=".hello"></activity>
        <service android:enabled="true" android:name=".service" />
    </application>
</manifest>

autostart.java

public class autostart extends BroadcastReceiver 
{
    public void onReceive(Context context, Intent arg1) 
    {
        Intent intent = new Intent(context,service.class);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(intent);
        } else {
            context.startService(intent);
        }
        Log.i("Autostart", "started");
    }
}

service.java

public class service extends Service
{
    private static final String TAG = "MyService";
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    public void onDestroy() {
        Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
        Log.d(TAG, "onDestroy");
    }

    @Override
    public void onStart(Intent intent, int startid)
    {
        Intent intents = new Intent(getBaseContext(),hello.class);
        intents.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intents);
        Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
        Log.d(TAG, "onStart");
    }
}

hello.java - This will pop-up everytime you start the device after executing the Applicaton once.

public class hello extends Activity 
{   
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Toast.makeText(getBaseContext(), "Hello........", Toast.LENGTH_LONG).show();
    }
}
Nathan
  • 7,853
  • 4
  • 27
  • 50
Lalit Poptani
  • 67,150
  • 23
  • 161
  • 242
  • 15
    +1 for complete example. Maybe I should change my IntentService with onHandleIntent to a plain old Service – Gady Oct 07 '11 at 17:20
  • 6
    This solved it ultimately. The problem was a combination of my service being an IntentService instead of plain old Service and errors in the service code. The thoroughness of this answer and logging in Android helped me solve my issues. – Gady Oct 10 '11 at 18:51
  • 3
    +1 for the detailed example. Would this also work without an activity? – balas Nov 12 '13 at 10:44
  • My service is on configurations -> applications. But on configurations -> running there is not my service name. Is it alright? I think no, because I can't see toast notifications. – Carlos Porta Jul 26 '14 at 01:30
  • I have heard that sometimes the android system can kill services.... Is that true? Will your example work forever no matter what? – Ruchir Baronia Jan 10 '16 at 17:13
  • What makes the broadcast receiver start when the phone is booted? Thanks! – Ruchir Baronia Feb 04 '16 at 03:33
  • @RuchirBaronia because we have register BroadCast Receiver with BOOT_COMPLETED action in Android Manifest File – Lalit Poptani Feb 04 '16 at 06:04
  • unfortunately in marshmallow after app finishes my service fishes too. how I can prevent service from stopping? thanks – Mahdi Mar 02 '16 at 14:05
  • @Kenji This answer is not related to your question, better would be to ask a seperate question – Lalit Poptani Mar 14 '16 at 06:08
  • 2
    onStart() callback is deprecated. You should use onStartCommand() instead. – mmBs May 18 '16 at 13:52
  • 1
    @mmBs this answer is almost 5 years old, so its obvious – Lalit Poptani May 18 '16 at 14:09
  • @LalitPoptani that's correct but still, 5 years ago this method has been already deprecated ;) – mmBs May 18 '16 at 14:14
  • Will this work if application is just installed and not opened any time? If no, then what would be the solution (in lollipop 5.1.1)? I want to start on_boot_completed broadcast receiver just without opening the app. (I think this my question is similar to @balas "Would this also work without an activity?" Please correct me if i am wrong here) – Nirav Khatri Jan 23 '17 at 09:44
  • 1
    @userAndroid I don't think so.As of 3.1 newly installed apps are in the "stopped state" and won't receive broadcasts or anything else. I'm running into this now. My app won't be in the app store so I think I will script the install and run the app via adb the first time. https://code.google.com/p/android/issues/detail?id=18225 – Bob Apr 05 '17 at 20:28
  • You can continue the service by adding android:stopWithTask="false" to the service in the Android Manifest. If you want to save information before the application is killed override onTaskRemoved – Braden Brown Jun 28 '18 at 19:41
  • One thing to note with starting on boot is that it can take a minute or so to actually start up. So if it doesn't start immediately give it some time before deciding it doesn't work – Braden Brown Jun 29 '18 at 16:02
  • 1
    I tried with my custom broadcat message "com.me.broadcast". I sent broadcast using command: adb shell am broadcast -a com.me.broadcast but it did not worked. – Trismegistos Jul 18 '18 at 23:44
  • `` What is that?! Why do you add as manifest attribute? – user924 Feb 21 '19 at 12:09
  • It gave me `main activity not found` – Hasan A Yousef Sep 19 '20 at 14:14
  • You should check on the intent's action in your `BroadcastReceiver`'s `onReceive` function for the `BOOT_COMPLETED `, otherwise, your app could be spoofed by other apps sending you intents which will cause a misleading behavior. – blueware Dec 06 '20 at 16:09
  • @LalitPoptani will the service start on its own or we need to open the app first ? – Lonko Dec 09 '20 at 20:31
4

Following should work. I have verified. May be your problem is somewhere else.

Receiver:

public class MyReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BOOT_COMPLETED.equals(arg1.getAction())) {
            Log.d("TAG", "MyReceiver");
            Intent serviceIntent = new Intent(context, Test1Service.class);
            context.startService(serviceIntent);
        }
    }
}

Service:

public class Test1Service extends Service {
    /** Called when the activity is first created. */
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("TAG", "Service created.");
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("TAG", "Service started.");
        return super.onStartCommand(intent, flags, startId);
    }
    
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Log.d("TAG", "Service started.");
    }
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
}

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.test"
      android:versionCode="1"
      android:versionName="1.0"
      android:installLocation="internalOnly">
    <uses-sdk android:minSdkVersion="8" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
    
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.BATTERY_STATS" 
    />
<!--        <activity android:name=".MyActivity">
            <intent-filter>  
                <action android:name="android.intent.action.MAIN" /> 
                <category android:name="android.intent.category.LAUNCHER"></category> 
            </intent-filter>
       </activity> -->
        <service android:name=".Test1Service" 
                  android:label="@string/app_name"
                  >
        </service>
        <receiver android:name=".MyReceiver">  
            <intent-filter>  
                <action android:name="android.intent.action.BOOT_COMPLETED" /> 
            </intent-filter>  
        </receiver> 
    </application>
</manifest>
Stypox
  • 963
  • 11
  • 18
Vivek
  • 4,170
  • 6
  • 36
  • 50
  • Thanks for this, but it still didn't work. Logs don't even show that it makes it to the StartupIntentReceiver. Any other ideas? – Gady Oct 07 '11 at 20:15
  • 1
    Is your code is working in emulator? Can you able to receive intent in emulator? – Vivek Oct 07 '11 at 20:36
  • I tested in the emulator and I get an error in DDMS, but it looks like at least the service is attempting to start, although none of my `Log()` statements are in there and the emulator device doesn't show my service as running in OS settings. Here is the error in DDMS: `System.err - at com.phx.batterylogger$1.onReceive(BatteryLogger.java:43)` Does that mean the issue is on line 43 of my BatteryLogger service? – Gady Oct 07 '11 at 20:53
3

Your Service may be getting shut down before it completes due to the device going to sleep after booting. 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 permission:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
phreakhead
  • 14,721
  • 5
  • 39
  • 40
  • 1
    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
3

I have found a way to make your application run well when the device reboots, please follow the steps below to be successful.

AndroidManifest file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="pack.saltriver" android:versionCode="1" android:versionName="1.0">
    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name=".UIBootReceiver" android:enabled="true" 
        android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
         <service android:name=".class_Service" />
    </application>
</manifest>

UIBootReceiver

public class UIBootReceiver extends BroadcastReceiver {

private static final String TAG = "UIBootReceiver";

    @Override
    public void onReceive(Context context, Intent arg1)
    {
        Toast.makeText(context, "started", Toast.LENGTH_SHORT).show();
        Intent intent = new Intent(context,class_Service.class);
        context.startService(intent);
    }
  }

This is asking permission to not need to manage battery saving for this app so you can run in the background stably.

Declare this code in onCreate () of MainActivity class:

    Intent myIntent = new Intent();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
    {
        myIntent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
        myIntent.setData(Uri.parse("package:" + 
            DeviceMovingSpeed.this.getPackageName()));
    }
    startActivity(myIntent);
Huy TRAN
  • 71
  • 6
1

Looks very similar to mine but I use the full package name for the receiver:

<receiver android:name=".StartupIntentReceiver">

I have:

<receiver android:name="com.your.package.AutoStart"> 
Community
  • 1
  • 1
ciscogambo
  • 1,160
  • 11
  • 18
1

I've had success without the full package, do you know where the call chain is getting interrupted? If you debug with Log()'s, at what point does it no longer work?

I think it may be in your IntentService, this all looks fine.

Phix
  • 9,364
  • 4
  • 35
  • 62
  • I added `Log.v("BatteryLogger", "Got to onReceive, about to start service");` to the onReceive handler, and it never shows up in the logs. So the listener is failing(?) – Gady Oct 07 '11 at 17:16
  • What makes the broadcast receiver start when the phone is booted? Thanks! – Ruchir Baronia Feb 04 '16 at 03:34
  • Boy. I haven't touched android in a few years. Sorry @Ruchir – Phix Feb 04 '16 at 05:23