// BootReceiver.java
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
// 啟動 Service、彈出 Dialog (需 TYPE_SYSTEM_ALERT 權限)、啟動 WorkManager 等
Intent service = new Intent(context, MyStartupService.class);
context.startService(service);
}
}
}
| 原因 | 檢查/修正 |
|---|---|
| 未聲明 RECEIVE_BOOT_COMPLETED 權限 | Manifest 加入 <uses-permission> |
receiver 未設 android:exported="true" | Android 12+ 必須顯式聲明 |
| App 安裝在 SD 卡 | Manifest android:installLocation="internalOnly" |
| 用戶強制停止過 App | Android 3.7+ 強制停止後需手動啟動一次才能收到開機廣播 |
| Doze/待機模式延遲 | 廣播屬「隱式廣播」,Android 8+ 可能延遲,重要任務改用 WorkManager setRequiredNetworkType |
| 模擬器/裝置未真正完成開機 | adb shell am broadcast -a android.intent.action.BOOT_COMPLETED 模擬測試 |
// 啟動時排程週期性/一次性工作,系統保證執行,無需監聽開機廣播
PeriodicWorkRequest syncWork = new PeriodicWorkRequest.Builder(SyncWorker.class, 24, TimeUnit.HOURS)
.setConstraints(new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build())
.build();
WorkManager.getInstance(context).enqueueUniquePeriodicWork("daily_sync", ExistingPeriodicWorkPolicy.KEEP, syncWork);
WorkManager 內部處理開機重排程、Doze 模式、電池優化,比手寫 BootReceiver + Service 魯棒得多。
# 發送開機廣播 (需 root 或模擬器)
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -p com.your.package
# 查看接收器是否註冊
adb shell dumpsys package com.your.package | grep -A5 "BOOT_COMPLETED"
# 檢查權限
adb shell pm grant com.your.package android.permission.RECEIVE_BOOT_COMPLETED