首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 開機自動啟動 Service 完整實作與常見坑點

     編輯:程式設計綜合問答

Android 開機啟動 Service 需「權限 → 接收開機廣播 → 啟動 Service」三步驟。常見失敗原因在於 Intent Filter 拼寫錯誤(如多底線)、Android 8+ 隱式廣播限制、或 Service 未在 Manifest 註冊。

標準實作三步驟

1. 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>

2. BroadcastReceiver 實作


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");
        }
    }
}

3. Service 實作(前台服務範例)


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_COMPLETED
  • ❌ Receiver android:exported="false" → ✅ true (API 26+)
  • ❌ 缺少 RECEIVE_BOOT_COMPLETED 權限
  • ❌ Service 未在 Manifest 宣告
  • ❌ Android 8+ 未使用 startForegroundService 或缺少前台通知

替代方案:WorkManager (推薦現代專案)


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 自動處理版本相容、電池優化、開機延遲,適合非即時性背景工作。

遵循標準流程並注意版本差異,即能可靠實現開機自啟服務。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved