How to fix BOOT_COMPLETED not working Android
Asked Answered
C

10

73

I know there has been hundreds of this kind of question asked, but I've been checking them all for a while and still couldn't find any solution.

I've seen this answer to "Android BOOT_COMPLETED not received when application is closed" said BOOT_COMPLETED not send to application unless user launch your application first, after Android version 3.1, but I still see some applications are doing that, so there must be a way. I really need to handle it, otherwise I'm also against to do something without user's interaction.

Here's my AndroidManifest:

<manifest ... >

<!-- to be activated service on boot is completed -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />

<application ... >
    <!-- to receive data when boot completed -->
    <receiver
        android:name="myPackage.BootReceiver"
        android:enabled="true"
        android:exported="true"
        android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
</application>
</manifest>

Edit: There is no much thing to see in my broadcastreceiver but to whom required here it is:

package myPackage
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    Utils.LogI("BootReceiver", "BootReceiver received!");
    if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
        // Do my stuff
    }
}
}
Corneliacornelian answered 7/12, 2013 at 12:22 Comment(1)
Which device are you using for testing? If its HTC - #10412231Surplus
W
91

This below thing worked for me

AndroidManifest.xml

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

<application>    

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

    <service android:name="NotifyingDailyService" />

BootCompletedReceiver.class

public class BootCompletedReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent arg1) {
        // TODO Auto-generated method stub
        Log.w("boot_broadcast_poc", "starting service...");
        context.startService(new Intent(context, NotifyingDailyService.class));
    }
}

Service.class

public class NotifyingDailyService extends Service {

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int onStartCommand(Intent pIntent, int flags, int startId) {
        // TODO Auto-generated method stub
        Toast.makeText(this, "NotifyingDailyService", Toast.LENGTH_LONG).show();
        Log.i("com.example.bootbroadcastpoc","NotifyingDailyService");
    
        return super.onStartCommand(pIntent, flags, startId);
    }
}
Walkabout answered 7/12, 2013 at 12:36 Comment(6)
@KarueBensonKarue You need to open your app at least one time after installed it. Or you might accidentally "Force Stop" it which in turn prevents broadcasts to be received.Bespoke
This won't work anymore https://mcmap.net/q/275469/-android-boot_completed-not-received-when-application-is-closed (3.1+)Horsemint
I checked out the link you refered, maybe you misunderstand about that. it is stop-state of a application not activity. 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. *Clowers
It will not work when you build Android with targetAndroidSDK 27 to above.Gustatory
Worked for me after adding <category android:name="android.intent.category.DEFAULT" /> to intent-filterBerberine
How can you read Log.w("boot_broadcast_poc", "starting service..."); since after reboot the device is not connected to Android Studio?Attica
C
59

This is an old and basic question but a lot of Android developers now still confused about this trouble, because THEY DON'T TAKE TIME TO READ THE DOCS CAREFULLY

I saw someone shared some links and said that: "This won't work anymore", it's totally wrong and misunderstood.

About this concern: "I've seen this answer said BOOT_COMPLETED is not sent to the application unless the user launches your application first, after Android version 3.1", please read these lines (from official docs: https://developer.android.com/about/versions/android-3.1.html#launchcontrols) to understand correctly:

  • Note that an application's stopped state is not the same as an Activity's stopped state. The system manages those two stopped states separately.

  • 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). (They mean force stop an app)

enter image description here

  1. That means a user should launch app at least once after installation to activate the application, then the app can receive implicit broadcasts from OS as normal. (Just only one time launching ever !)

  2. "Does any app that gets installed and never open even only one time ever ?", yep, it 's spam and scam apps, this technique helps user to prevent that!

FURTHERMORE, UNTIL NOW (Android Oreo 8.0), when Android limits registering implicit broadcasts at Manifest (https://developer.android.com/about/versions/oreo/background.html#broadcasts), several broadcasts are still currently exempted from these limitations. And BOOT_COMPLETED is the first one they mention ! (https://developer.android.com/guide/components/broadcast-exceptions.html)

By the way, this is the best solution I found for this question:

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

<receiver android:name=".BootReceiver" android:enabled="true" android:exported="true">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT"/>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
                <!--For HTC devices-->
                <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
            </intent-filter>
        </receiver>

Finally, please read the document carefully and Think twice code once :3!

Clowers answered 19/9, 2017 at 7:41 Comment(12)
but BOOT completed action is not working on one plus device do u have any alternative fot thatCown
@FerozSiddiqui did you try <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/> ?Clowers
I have tested in Orio not working. Very informative though, thanksHominid
It's not working on mi and one plus phones double checked it.Cown
This has to do with battery optimization. If you remove your app from batter optimization it will workCown
This Should be the Accepted Answer. It works for me on samsung m20 and on emulator running android 10.Leprosy
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.Vasectomy
@ThinkTwiceCodeOnce Any reason for having exported flag as true here?Alvin
@Think Twice Code Once Hi, I have a similar use case. Why do you use '<category android:name="android.intent.category.DEFAULT"/>' in the <intent-filter> ?Editheditha
Please update the answer, it's not working anymore in 2022Prelature
it's not working in my mi android 11 deviceMauldon
Why do you set android:exported="true"?Attica
H
10

Some new tablets and android devices have a security application by default. Sometimes these apps block your auto-start mode. An example of these secure apps is MyAsus manager. In this case, the user needs to add "allow auto start" inside the app manager for all the apps that want to receive this BOOT_COMPLETED

Hopfinger answered 23/12, 2016 at 20:31 Comment(2)
it's possible to do that programmatically?Ariadne
the same is happening for Huiwei phones. BOOT_COMPLETED is not triggered. To make it fired, you as a user should go to the Settings->Apps->App launch-> turn off for a needed app.Ashton
F
9

And for Htc devices add com.htc.intent.action.QUICKBOOT_POWERON

    <receiver android:enabled="true" android:name=".receivers.BootUpReceiver">
        <intent-filter>
            <category android:name="android.intent.category.DEFAULT" />
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
            <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
         </intent-filter>
    </receiver>
Frankly answered 6/3, 2017 at 9:52 Comment(0)
D
8

For others that are still having an issue with this like I did, if you're debugging on a device that has a boot lock (pin, pattern, or otherwise), OS versions >= 7.0 need to subscribe to the android.intent.action.LOCKED_BOOT_COMPLETED as illustrated below:

<receiver
    android:directBootAware="true"
    android:name=".BootCompletedReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT" />
        <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
        <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
</receiver>

You can find the documentation at the following link: https://developer.android.com/training/articles/direct-boot

Diabolic answered 25/2, 2020 at 21:23 Comment(1)
Dos this apply also to EMUI phones that you know? Would it be possible to launch context.startForegroundService after reboot?Attica
L
6

The problem is with the device. some devices only allow internal apps to receive this action(example: Android 5.1).

you can add this to your intent filter as work around

action android:name="android.intent.action.USER_PRESENT"

This is triggered after the user unlocks the device.

Longsufferance answered 25/5, 2017 at 9:39 Comment(0)
M
1

The problem I experienced was that BOOT_COMPLETED and QUICKBOOT_POWERON together does not always triggered my intent when I switched the power off from my Android 6.0.1 panel. I have been searching the Internet for quite a long time and found the solution by adding QUICKBOOT_POWEROFF to the manifest file.

See also:

HTC's "fast boot" is not broadcasting BOOT_COMPLETED intent nor wiping intents from alarm manager

Malaguena answered 22/2, 2019 at 10:8 Comment(0)
L
1

If you reached this answer and none of the other answers seem to work, double-check the action string in the manifest. AndroidStudio does not show any error if you write an incorrect string in the action tag. Do not confuse the name of the constant in code, which is ACTION_BOOT_COMPLETED, with the value of said constant, which is the one that goes in the manifest, and is equal to android.intent.action.BOOT_COMPLETED

TL;DR Check that you have this in the manifest:

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

And not this:

<intent-filter>  
    <action android:name="android.intent.action.ACTION_BOOT_COMPLETED" />  
</intent-filter>  
Legroom answered 18/5, 2022 at 9:48 Comment(0)
J
0

This is unfortunately a more frequent issue these days, thanks to OEMs like Samsung, Huawei, OnePlus and Xiaomi blocking BOOT_COMPLETED by default for almost all apps.

Auto-launch is not a standard permission you can detect or request, but you can detect when this is happening:

  • Mark when the receiver last ran and store the result in shared prefs.
  • Use System.currentTimeMillis() - SystemClock.elapsedRealtime() to get the last boot time.

Then you can warn the user if the boot was >5 minutes ago and the receiver never ran.

You can warn them and prompt them to open their app details page:

val packageName = BuildConfig.APPLICATION_ID
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data = Uri.parse("package:$packageName")
startActivity(intent)

There are some other approaches for trying to open the auto-launch permissions page, but they are not particularly reliable, because every OEM has their own custom page to configure it; and some you aren't even allowed to open. I go over more specifics in this post.

Jeramey answered 11/12, 2023 at 4:9 Comment(0)
L
-2

For workaround you need to create a NotificationListener service

if the Device is >= Build.VERSION_CODES.JELLY_BEAN_MR2 and having a battery optimization option as in Huawei devices, then you have to ask for NotificationListener permission and create a NotificationListener service as in below code, then you will get the BOOT_COMPLETED in your receiver

Manifest Receiver :

    <receiver
                android:name=".TestRes"
                android:enabled="true"
                android:exported="true">
                <intent-filter android:priority="1">
                    <category android:name="android.intent.category.DEFAULT"/>
                    <action android:name="android.intent.action.BOOT_COMPLETED"/>
                    <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
                    <action android:name="android.intent.action.USER_PRESENT"/>
                    <action android:name="android.intent.action.REBOOT"/>
                </intent-filter>
 </receiver>

1 create a NotificationListener service :

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public class DevAppNotificationListener extends NotificationListenerService {

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
//        super.onNotificationPosted(sbn);
    }

    @Override
    public void onNotificationRemoved(StatusBarNotification sbn) {
   //     super.onNotificationRemoved(sbn);
    }


}

2 check if the NotificationListener is granted or not :

static boolean CheckNotificationLisPermission(Context context)
    {

        return NotificationManagerCompat.getEnabledListenerPackages (context).contains(context.getApplicationContext().getPackageName());

    }

3 if not then ask for NotificationListener permission :

 Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
            context.startActivityForResult(intent, callBackResultIntent);
Lianneliao answered 7/6, 2019 at 17:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.