36

I am aware that this question has been asked a lot on the site, however, I cant seem to find a solution. My BOOT_COMPLETED receiver is not called when the application is not running.

Manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.startuptest"
    android:versionCode="1"
    android:versionName="1.0"
    android:installLocation="internalOnly">
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.startuptest.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name="com.example.startuptest.StartUpBootReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

StartUpBootReceiver:

public class StartUpBootReceiver  extends BroadcastReceiver {

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

        Log.d("startuptest", "StartUpBootReceiver " + intent.getAction());

        if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
            Log.d("startuptest", "StartUpBootReceiver BOOT_COMPLETED");
        }
    }
}

If the application is running and I simulate a call with

adb shell
am broadcast -a android.intent.action.BOOT_COMPLETED

The event is received correctly, however, if the application is closed the event is not receieved, nor is it received at start up.

I have installed the application then launched it a couple of times to make sure it is registered. I'm pretty lost on this one so any advice would be highly appreciated.

Edit: I can see in the logs that all the other closed applications (Youtube, FileObserver, etc) receive the boot_completed event, just not mine.

frogatto
  • 28,539
  • 11
  • 83
  • 129
user346443
  • 4,672
  • 15
  • 57
  • 80

9 Answers9

110

Starting with Android 3.1 all applications, upon installation, are placed in a "stopped" state.(This is the same state that the application ends up in after the user force-stops the app from the Settings application.)

Android stopped state

While in "stopped" state, the application will not run for any reason, except by a manual launch of an activity. (Meaning no BroadcastReceviers(ACTION_PACKAGE_INSTALLED, BOOT_COMPLETED etc.) will be invoked, regardless of the event for which they have registered, until the user runs the app manually.)

This is an anti-malware move by Google. Google has advocated that users should launch an activity from the launcher first, before that application can go do much. Preventing BOOT_COMPLETED from being delivered until the activity is launched is a logical consequence of the that argument.

More details about this:
http://developer.android.com/about/versions/android-3.1.html#launchcontrols
http://commonsware.com/blog/2011/07/05/boot-completed-regression.html
http://devmaze.wordpress.com/2011/12/05/activating-applications/

Caner
  • 57,267
  • 35
  • 174
  • 180
  • 2
    this answer is must read if you have app with only `BroadcastReceiver` and `Service` for it – Akhil Jain Aug 13 '14 at 18:38
  • 1
    This [link](https://possiblemobile.com/2014/06/effects-android-application-termination/) also covers the related topic. – stdout Aug 09 '16 at 10:27
  • 1
    But then what is the point of registering a boot complete broadcast in the first place? The way I see it, if I not able to take any action/do something in the time after the device is booted and before the app is launched by the user, then what purpose will registering a boot complete receiver solve? – Bluesir9 Jul 31 '17 at 14:55
  • 3
    @Bluesir9 I was confused as you are, but after few hours reading around, I got these ideas. **Applications are in a stopped state when they are first installed but are not yet launched and when they are manually stopped by the user (in Manage Applications).** That means, user should launch app **at least once after installation to activate the application**, then the app can receive all implicit broadcast from OS as normal. – Phong Nguyen Sep 19 '17 at 04:48
  • 1
    take a look at my answer to get more detail: https://stackoverflow.com/questions/20441308/boot-completed-not-working-android/46294732#46294732 – Phong Nguyen Sep 19 '17 at 07:48
  • 1
    Might not affect many of you, but it could be of someone else's interest: in my case it was an option to compile my app as a system app into an Android ROM. Seems like system apps are NOT in the "stopped state" by default, so I was able to bake an app without an activity into an Android build and its service was started automatically because it could receive the BOOT_COMPLETED intent. Tested with AOSP API version 29. – Nico Feulner Aug 26 '20 at 11:28
41

I start my app when the BOOT_COMPLETED, so I know it's working. I add Log.d it won't show. I add Toast it show. Small differents in Manifest.xml

<receiver android:name="com.example.startuptest.StartUpBootReceiver">
    <intent-filter>
         <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>            
</receiver>
user924
  • 8,146
  • 7
  • 57
  • 139
Gina
  • 902
  • 8
  • 15
  • 1
    I had left out the Default tag – user346443 Jul 02 '13 at 07:02
  • 4
    Thanks, this did the trick. `android:enabled="true" android:exported="true"` are also required so Android knows about this receiver. – Ketan Mar 24 '14 at 00:09
  • 6
    But aren't these the defaults. http://developer.android.com/guide/topics/manifest/receiver-element.html – MZB Sep 19 '14 at 18:21
  • You'll receive the Log.d on another process console in the Android monitor because exported="true" makes the receiver as a new process – Samuel Robert Jun 27 '16 at 16:28
  • 1
    @Ketan these two are true by default - if something started working likely you just turned on "run in background" on meizu flyme, or added application to protected on huawei or whatever may surprisingly happen on contemporary phones. Except maybe for priority=999. – Boris Treukhov Jan 04 '18 at 19:16
  • 1
    `` and `android:enabled="true" android:exported="true"` aren't needed – user924 Feb 21 '19 at 13:35
  • In my experience android:exported is not required. But the enabled flag is required. – Jayakrishnan Jul 09 '19 at 16:08
  • @Jayakrishnan `enabled` is `true` by default – user924 Dec 24 '20 at 14:38
  • `export` is providing components of your app to other apps – user924 Dec 24 '20 at 14:39
29

Each answer here add a small piece of information, so here is the summary of it all:

To make sure you will receive the BOOT_COMPLETED make sure you do the following:

  1. Add your receiver to manifest (don't forget the flags):

    <receiver android:name="com.yourpacakge.BootReceiver" android:exported="true" android:enabled="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </receiver>
    
  2. Add permission:

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

  3. After installing your app, it needs to be lunch at least once, manually by the user, in order to receive Boot complete event.(More details)

Community
  • 1
  • 1
Ilya Gazman
  • 31,250
  • 24
  • 137
  • 216
  • 1
    I am seeing that [on Marshmallow at least] if I Force Close my app, then the BroadcastReceiver onReceive never fires. Is this true, and if so is there any way around this? – swooby Oct 23 '15 at 22:44
  • 3
    But why is the default needed? – JacksOnF1re May 24 '16 at 22:54
  • 1
    This stuff has nothing to do with Boot Receiver so you can remove it: `` and `android:enabled="true" android:exported="true"` They aren't needed – user924 Feb 21 '19 at 13:44
2

was struggling with the same problem, the reason is you are using Log.d to track you application in logcat, unfortunately when you restart your phone the application is receiving the BOOT_Complete but you can't see it because it's not logging to logcat.

try making a Toast with some text instead of Log.d to make sure if BOOT_COMPLETED is or is not received.

hope this Help.

Tarek K. Ajaj
  • 2,461
  • 1
  • 19
  • 24
2

Heres a C# version if you guys want it. My tests show that it works pretty much flawlessly and the startup is quite fast. Though do note that adding it both in C# and in AndroidManifest.xml breaks it(for me at least).

I have also added some nice and useful examples that I wished I had found out from someone instead of learning it myself when reading through the documentaries and such.

[BroadcastReceiver(Enabled = true, Exported = true, DirectBootAware = true, Name = "com.nevaran.startup.StartUpBootReceiver")]
[IntentFilter(new string[] {
    Intent.ActionBootCompleted
    , Intent.ActionLockedBootCompleted
    , Intent.ActionMyPackageReplaced
    , Intent.ActionUserInitialize
    , "android.intent.action.QUICKBOOT_POWERON"
    , "com.htc.intent.action.QUICKBOOT_POWERON"
})]
public class BootReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
         if(    intent.Action.Equals(Intent.ActionBootCompleted)
             || intent.Action.Equals(Intent.ActionLockedBootCompleted)
             || intent.Action.Equals(Intent.ActionUserInitialize)
             || intent.Action.Equals("android.intent.action.QUICKBOOT_POWERON")
             || intent.Action.Equals("com.htc.intent.action.QUICKBOOT_POWERON")
           )
        {
            //run code here only if its started by the chosen actions
        }
        //some code that doesnt care about which action is triggered by
    }
}
Nevaran
  • 137
  • 9
0

To resolve this problem, you can use firebaseJobDispatcher to invoke automatically , firebaseJobDispatcher will have code to reactive your services, yes after a certain time services may stopped by OS, but your firebaseJobDispatcher will reactivate your services again. FirebaseJobDispatcher has lots of properties from where you can define the scope of this;

how it works, for more detail https://github.com/firebase/firebase-jobdispatcher-android

Abdul Rizwan
  • 3,904
  • 32
  • 31
  • firebaseJobDispatcher needs to be created programmatically. It can't be started automatically thus we need to listen to BOOT_COMPLETED event. – Edijae Crusar Mar 27 '19 at 13:25
0

Adding the following seemed to work for me along with the BOOT_COMPLETED intent action

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

If you want to know the actual reason behind why BOOT_COMPLETE is not working or not receiving. I will suggest you to go to the OFFICIAL Android develop site. They have explained with exact solution.

Android developer - BOOT_COMPLETE

10 Rep
  • 2,217
  • 7
  • 19
  • 33
Sankar Behera
  • 831
  • 10
  • 10
-3

Basically you need android:enabled="true" android:exported="true" flags in manifest to receive the broadcast.

<receiver android:name=".bootReceiver" 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>
sgupta
  • 535
  • 4
  • 8
  • This stuff has nothing to do with Boot Receiver so you can remove it: `` and `android:enabled="true" android:exported="true"` They aren't needed – user924 Feb 21 '19 at 13:48
  • @user924 can you explain why there is no need in category.DEFAULT? – Johnny Five Dec 20 '19 at 14:09
  • 1
    @JohnnyFive because it works without and you can check some examples on android.com site, it's not needed – user924 Dec 24 '20 at 14:42