Android - Start service on boot

JavaAndroidBroadcastreceiverIntentservice

Java Problem Overview


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.

Java Solutions


Solution 1 - Java

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();
    }
}

Solution 2 - Java

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>

Solution 3 - Java

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" />

Solution 4 - Java

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);

Solution 5 - Java

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"> 

Solution 6 - Java

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.

Solution 7 - Java

Just to make searching easier, as mentioned in comments, this is not possible since 3.1 https://stackoverflow.com/a/19856367/6505257

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGadyView Question on Stackoverflow
Solution 1 - JavaLalit PoptaniView Answer on Stackoverflow
Solution 2 - JavaVivekView Answer on Stackoverflow
Solution 3 - JavaphreakheadView Answer on Stackoverflow
Solution 4 - JavaHuy TRANView Answer on Stackoverflow
Solution 5 - JavaciscogamboView Answer on Stackoverflow
Solution 6 - JavaPhixView Answer on Stackoverflow
Solution 7 - JavaMrKewView Answer on Stackoverflow