The question:
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
}
}
}
The Solutions:
Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.
Method 1
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" >
</service>
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);
}
}
Method 2
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)
-
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 !) -
“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!
Method 3
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>
Method 4
some new tablets and android devices have security application by default. some times these apps lock your auto-start mode. an example of this secure app is MyAsus manager. so you can add “allow auto start” to your apps
Method 5
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
Method 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.
Method 7
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
Method 8
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>
Method 9
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);
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0