74

I've looked around here for similiar problems, but for some reason my BroadcastReceiver never ends up receiving the android.intent.action.BOOT_COMPLETED Intent.

Here is my (relative) Android.Manifest File:

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

        </intent-filter>
    </receiver>

And Here is the actual Receiver.

public class BootReceiver extends BroadcastReceiver {
private static final String TAG="BootReceiver";

@Override public void onReceive(Context context,Intent intent){
    try{
        context.startService(new Intent(context,ConnectivityListener.class));
        Log.i(TAG,"Starting Service ConnectivityListener");
    }catch(Exception e){
        Log.e(TAG,e.toString());
    }
}
}

Thanks! Any help is greatly appreciated

apmeyers1987
  • 859
  • 1
  • 7
  • 11
  • 2
    Blind guess - your receiver is not in the main package and there is no package/mainpackage/BootReceiver.java, but instead package/mainpackage/receivers/BootReceiver.java, i.e. path to the receiver is wrong. – Kiril Kirilov Feb 19 '11 at 15:47
  • Thanks, I didn't think of checking that, but no luck it's definitely in the default package. – apmeyers1987 Feb 19 '11 at 19:58
  • 1
    This same problem could happen when the receiver declaration contains android:exported="true" would create new process all together for the receiver. Your logger (Log.i) would print the results in a new console that you wouldn't even notice under android monitor (Android Studio). I would recommend to remove this statement unless you know what it means. – Samuel Robert Jun 27 '16 at 02:52

9 Answers9

173

You can emulate all broadcast actions by connecting via adb to the device and open a device shell.

Here we go:

  • open console/terminal and navigating to /platform-tools
  • type adb shell or on linux/mac ./adb shell
  • in the shell type am broadcast -a android.intent.action.BOOT_COMPLETED or whatever action you want to fire

There are a bunch of nice commands coming with adb or the adb shell. Just try it

Regards Flo

edit: oh damn, i wanted this answer as an answer on the "had to turn phone on/off every time". sorry folks

Louis CAD
  • 10,965
  • 2
  • 39
  • 58
fklappan
  • 3,259
  • 2
  • 17
  • 18
  • 6
    Not at all what the initial question was asking (so no upvote), none the less, I found this very helpful, thankyou. – CoatedMoose May 30 '12 at 00:25
  • this was useful thank you. Now one question, calling this command it does work, but not with a simple boot. Any idea? – Rui Lima Oct 20 '12 at 23:15
  • 4
    On my device all works as expected. Did you have the permission in the manifest file: – fklappan Oct 23 '12 at 09:33
  • thnx dude u saved lot of time – Abhishek Chauhan Feb 24 '13 at 05:44
  • 13
    For reference, running this in adb on 4.2.2 will actually reboot your device – Luke May 08 '13 at 15:58
  • finally I've been able to restart the emulator. Thanks! – Bilbo Baggins Jul 15 '13 at 16:29
  • 9
    Most useful random answer ever – Alessandro Roaro Jan 07 '14 at 20:02
  • 29
    On newer Android versions, you need to run `adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -p com.mypackage.name`. Without restricting the broadcast to your app, your device will actually reboot. – blade Aug 10 '15 at 11:54
  • 3
    In my case it works without "-p" Like this: am broadcast -a android.intent.action.BOOT_COMPLETED com.mypackage.name – savante Aug 22 '15 at 00:59
  • Yeah, in my case as well "-p" option is not being recognized and it works fine without "-p". – Ravi Jun 01 '16 at 14:53
  • 9
    I get the following error when I am issuing this command `Broadcasting: Intent { act=android.intent.action.BOOT_COMPLETED } java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.BOOT_COMPLETED from pid=3566, uid=2000` – samsri Jan 29 '17 at 08:43
  • @SampathSurineni I believe you need a rooted device or an emulator to send this. – James Moore Mar 10 '17 at 18:02
  • 2
    For following exception: `java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.BOOT_COMPLETED` you need change adb to root: `./adb root` and then `adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -p yourpackage.app` will be works. – t0m Jun 14 '17 at 10:31
  • 2
    Typing in `adb shell am broadcast -a android.intent.action.ACTION_BOOT_COMPLETED` instead launched the boot broadcast for me. – Damien Doumer Jan 05 '20 at 19:37
164

I'm posting this in the hope that it will be helpful to someone who has tried everything but still cannot get it to run on boot after installation or it used to work before and doesn't work anymore.

So assuming you have added the permission:

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

And registered your receiver:

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

And coded your BroadcastReceiver:

public class StartUpBootReceiver extends BroadcastReceiver {

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

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

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 BroadcastRecevier(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 a design decision by Google to prevent malware apps. Google has advocated that users should launch an activity from the launcher first, before that application can do much. Preventing BOOT_COMPLETED from being delivered until the activity is launched is a logical consequence of that argument.

Once a user runs any activity in your app once, you will receive the BOOT_COMPLETED broadcast after all future boots.

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
  • 9
    +1 This is a great answer and I was not aware of this. One relevant bit of info is that since 3.1 _"... the system adds `FLAG_EXCLUDE_STOPPED_PACKAGES` to **all** broadcast intents."_ which results in the situation described in your answer - however - _"A background service or application **can override** this behavior by adding the `FLAG_INCLUDE_STOPPED_PACKAGES flag` to broadcast intents that should be allowed to activate stopped applications."_ I am yet to test this however :p (taken from the link you posted http://developer.android.com/about/versions/android-3.1.html#launchcontrols) – Dori Feb 18 '14 at 16:27
  • 14
    It should be clarified that once a user runs any activity in your app once, you will receive the BOOT_COMPLETED broadcast after all future boots. The one caveat to this is that if the user does Force Close on your app, they will have to start it manually again before you will receive BOOT_COMPLETED broadcasts again. – Splaktar Jul 26 '14 at 17:26
  • 1
    @Dori Were you able to verify the behavior of FLAG_INCLUDE_STOPPED_PACKAGES flag ? – ARK Apr 05 '16 at 19:56
  • You can't `addFlags` unless you have started your activity the first time, therefore this does not bypass the need to start the application for the first time. – tommed Aug 18 '16 at 18:16
  • 2
    Does an activated app remain activated, when it is updated to a new version? via app store or `adb install -r` ? – BeniBela Aug 19 '17 at 12:25
  • 2
    Does this apply to system apps as well? – JohnyTex Feb 21 '22 at 09:39
  • Also, can an explicit Intent put the app in a started state, even though the user has never opened an activity in it? – JohnyTex Feb 21 '22 at 09:40
  • @tommed but then you can have another app start an app that is in a stopped state, right? Because you had to start that other app first. – JohnyTex Feb 21 '22 at 09:48
  • if I click to start the app after ~10mins of booted it does not deliver broadcast to my app, I don't know why? – Mohd Qasim Jul 04 '23 at 06:35
59

If your app installed on external storage(SD card), you will never receive Boot Complete action. So you have to specify android:installLocation="internalOnly" in the manifest tag.

Sundeep1501
  • 1,510
  • 1
  • 18
  • 28
  • finally I have understood why my app is not started on boot up on some phones while on others it works OK - the matter was what storage is selected to install apps on by default. – Mixaz Jun 07 '16 at 13:15
  • 1
    It is not working on my lollipop 5.1.1 device also. It don't think it is possible to use BOOT_COMPLETED without launching the Activity. – Venugopal May 22 '19 at 02:30
15

Your <uses-permission> element needs to be an immediate child of the <manifest> element, and your code listing above suggests that it is not.

Here is a sample project demonstrating the use of BOOT_COMPLETED.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Sorry, it was a little misleading above since I only took snippets of the Manifest since It's very long, but the uses-permission is a direct child of – apmeyers1987 Feb 19 '11 at 20:01
  • 2
    +1 for mentioning the correct position of the -element. I got that wrong by having it as a child of which compiled without warnings or errors but of course did not work. – Father Stack Feb 24 '14 at 14:26
10

Turns out the receiver wasn't in the tag of the manifest. Whoops! Thanks for your help guys! The worst part about testing this is having to keep turning off and on the phone. :P

3lectrologos
  • 9,469
  • 4
  • 39
  • 46
apmeyers1987
  • 859
  • 1
  • 7
  • 11
  • 15
    as I read elsewhere on SO, you don't need to reboot but just a shell: `adb shell am broadcast -a android.intent.action.BOOT_COMPLETED` – vault May 21 '14 at 16:02
6

This seems to be the forefront thread for this problem, so I wanted to add a solution for my C# colleagues. I racked my brain trying to figure out what I was doing wrong after trying everything here, to no avail. I finally figure out what was wrong, and it differs a bit from the advice here for C# Mono development. Basically, it boils down to something I've just learned the hard way. With C# DO NOT MODIFY AndroidManifest.xml manually!

See this guide for reference: Xamarin: Working with AndroidManifest.xml

More directly for this problem, here is how you get this done.

First, in your project properties, under the Manifest Tab, there is a checkbox list for choosing the permissions you want to provide, one of which is RECEIVE_BOOT_COMPLETED. Check that to provide these permissions.

Secondly, you need to put the proper tags on your BroacastReceiver class.

[BroadcastReceiver]
[IntentFilter(new String[]{ Intent.ActionBootCompleted }, Priority = (int)IntentFilterPriority.LowPriority)]
public class MyBootReceiver : BroadcastReceiver
{
   public override void OnReceive(Context context, Intent intent)
   {
      // Do your boot work here, set alarms, show toasts, whatever
   }
}

The final part of [IntentFilter()] dealing with priority isn't required, it just lets other higher priority stuff get done first on boot, and is good practice if your App isn't a high priority thing.

As you'll see in the linked article, using these tags in your code will cause the AndroidManifest.xml file to be created at build time, with everything the way it should be. What I found was that when modifying the manifest manually to include the receiver tag, the system was causing it to look for the class one level too deep, thus throwing a ClassNotFound exception. It was trying to instantiate [Namespace].[Namespace].[BroadcastReceiver] which was wrong. And it was doing that because of the manual manifest edits.

Anyway, hope this helps.

Also, another quick tip with the adb tool. If you want to get an easier to read version of the log, try this:

C:\Android\platform-tools\adb logcat >> C:\log.txt

This will dump the logcat to a text file you can open and read a bit easier than in the command prompt window. Makes cut and paste of things a bit easier too.

Wanabrutbeer
  • 676
  • 6
  • 11
1

Pertaining to some devices running Android Kitkat 4.4.4_r2/r1.

There seems to be a bug in Android that make android.intent.action.BOOT_COMPLETED no being broadcasted.

See:
BOOT FAILURE making Package Manager Service ready

In most cases this is not the answer to your problems (more likely because permissions etc), but if you are running Kitkat then you might have a look and see if this seems to be the case for you.

I had this problem and android.intent.action.BOOT_COMPLETED would simply not be broadcasted some of the times it had started up!

JohnyTex
  • 3,323
  • 5
  • 29
  • 52
1

Other answers here already covered how to perfectly implement the Broadcast Receiver so that it'll work, however I still had problems receiving the BOOT_COMPLETED Intent until I realized the app was actually working when started from the phone/emulator by pressing on the app icon. Whenever I start my app with the debug/run commands from Android Studio the BOOT_COMPLETED Intent won't be delivered, unless the app is opened and running.

I hope this can help someone who, like me, was struggling for hours with this problem. Moreover, if anyone has an explanation for this behavior, I'd be really happy to know more about it.

samugi
  • 395
  • 5
  • 17
0

on adding <category android:name="android.intent.category.HOME" /> this to my manifest file solve my problem and works.

<receiver android:name=".BroadCastRecieverClass">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <category android:name="android.intent.category.HOME" />
        </intent-filter>
    </receiver>
Ayaz khan
  • 153
  • 5
  • 16