Android 開機啟動 Service 需「權限 → 接收開機廣播 → 啟動 Service」三步驟。常見失敗原因在於 Intent Filter 拼寫錯誤(如多底線)、Android 8+ 隱式廣播限制、或 Service 未在 Manifest 註冊。
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- Android 9+ 前台服務需此權限 -->
<application ...>
<receiver
android:name=".BootReceiver"
android:enabled="true"
android:exported="true"> <!-- Android 8+ 必須 exported=true -->
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" /> <!-- 正確拼寫:無底線 -->
</intent-filter>
</receiver>
<service
android:name=".MyService"
android:enabled="true"
android:exported="false" />
</application>
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Intent serviceIntent = new Intent(context, MyService.class);
// Android 8+ 必須用 startForegroundService
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(serviceIntent);
} else {
context.startService(serviceIntent);
}
Log.d("BootReceiver", "Service started at boot");
}
}
}
public class MyService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 建立前台通知(Android 8+ 強制)
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("背景服務運行中")
.setContentText("點擊查看")
.setSmallIcon(R.drawable.ic_notification)
.build();
startForeground(1, notification);
// 執行實際工作...
return START_STICKY; // 被殺後嘗試重啟
}
// onBind, onCreate, onDestroy 等...
}
| Android 版本 | 關鍵限制 | 應對 |
|---|---|---|
| 8.0 (API 26) | 隱式廣播限制、後台服務限制 | Receiver 設 exported=true、用 startForegroundService、建立 Notification Channel |
| 9.0 (API 28) | FOREGROUND_SERVICE 權限必須 | Manifest 加入權限 |
| 10 (API 29) | 開機廣播延遲發送 | 不依賴即時性、接受延遲 |
| 12 (API 31) | 精確鬧鐘權限 | 若用 AlarmManager 需 SCHEDULE_EXACT_ALARM |
android.intent.action._BOOT_COMPLETED(多底線)→ ✅ android.intent.action.BOOT_COMPLETEDandroid:exported="false" → ✅ true (API 26+)RECEIVE_BOOT_COMPLETED 權限startForegroundService 或缺少前台通知
PeriodicWorkRequest work = new PeriodicWorkRequest.Builder(MyWorker.class, 15, TimeUnit.MINUTES)
.setInitialDelay(1, TimeUnit.MINUTES) // 開機後延遲
.addTag("boot_work")
.build();
WorkManager.getInstance(context).enqueueUniquePeriodicWork("boot_work", ExistingPeriodicWorkPolicy.KEEP, work);
WorkManager 自動處理版本相容、電池優化、開機延遲,適合非即時性背景工作。
遵循標準流程並注意版本差異,即能可靠實現開機自啟服務。