Android Oreo、Pie系统中Boot Broadcast Receiver失效及onReceive无响应问题
Let's break down why your BootReceived receiver isn't firing on Android 8.0+ and how to fix it step by step:
1. Verify Manifest Registration (Critical!)
First, double-check your AndroidManifest.xml setup—this is the most common culprit. For BOOT_COMPLETED to work, you need:
- The required permission
- A properly declared receiver with the correct intent filter, including
exported="true"(since the broadcast comes from outside your app)
Here's the correct manifest snippet:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <receiver android:name=".BootReceived" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <!-- Add this for devices like Samsung that use a custom boot action --> <action android:name="android.intent.action.QUICKBOOT_POWERON" /> </intent-filter> </receiver>
2. Adapt to Android Oreo's Background Service Restrictions
On Android 8.0+, you can't use startService() from a broadcast receiver (unless it's an immediate foreground service). Your current code will throw an IllegalStateException here. Instead, use startForegroundService() and make sure your MainService shows a foreground notification within 5 seconds:
Update your service startup code:
Intent tni = new Intent(context, MainService.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Start foreground service for Oreo+ context.startForegroundService(tni); } else { context.startService(tni); }
And in MainService.onCreate():
@Override public void onCreate() { super.onCreate(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Create a foreground notification NotificationChannel channel = new NotificationChannel("BOOT_SERVICE_CHANNEL", "Boot Service", NotificationManager.IMPORTANCE_LOW); NotificationManager manager = getSystemService(NotificationManager.class); manager.createNotificationChannel(channel); Notification notification = new NotificationCompat.Builder(this, "BOOT_SERVICE_CHANNEL") .setContentTitle("Service Running") .setContentText("Started on boot") .setSmallIcon(R.drawable.ic_notification) .build(); startForeground(1, notification); } }
3. Fix Toast Visibility & Logging
Sometimes, the Context from the broadcast receiver might not be valid for showing a Toast. Switch to using the application context to avoid this:
Toast.makeText(context.getApplicationContext(), "Boot completed!", Toast.LENGTH_LONG).show();
Also, prioritize checking Logcat for your IfWalaBooot tag—Toast might not appear during system boot, but logs will confirm if the receiver fired.
4. Check App State
If your app was force-stopped by the user (Settings > Apps > Your App > Force Stop), Android will block all broadcast receivers until the user manually opens the app once. This is a system-level restriction you can't bypass.
5. Test Correctly
- Avoid relying on emulator restarts—sometimes they don't send the
BOOT_COMPLETEDbroadcast properly. Use a physical device for testing. - You can manually trigger the broadcast via adb to test your receiver without rebooting:
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -n com.your.package.name/.BootReceived
Updated Receiver Code
Here's your revised BootReceived class incorporating all fixes:
public class BootReceived extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Intent.ACTION_BOOT_COMPLETED.equals(action) || "android.intent.action.QUICKBOOT_POWERON".equals(action)) { Log.d("IfWalaBooot", "Received action: " + action); Toast.makeText(context.getApplicationContext(), "Boot completed!", Toast.LENGTH_LONG).show(); // Start MainActivity with proper flags Intent intent1 = new Intent(context, MainActivity.class); intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); context.startActivity(intent1); // Start MainService with Oreo+ support Intent tni = new Intent(context, MainService.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { context.startForegroundService(tni); } else { context.startService(tni); } } } }
内容的提问来源于stack exchange,提问作者Pooja Malik

