BOOT_COMPLETED not working Android

Viewed 103926

First of all, 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 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, there must be a way. I really need to handle it, otherwise i'm also against to do something without user's interaction.

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

Thanks in advance.

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
    }
}
}
9 Answers

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

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>  

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