[Android] 如何開機就執行程式 – 使用 BroadcastReceiver

在做均鈺 (Hypro Enterprises) 專案的時候,發現為了保持服務的穩定,例如持續接收藍芽訊號,我們需要在使用者重新開機之後服務能夠自動開啟並且繼續下去,也就是說當手機重開的時候,我們設計的程式需要自動偵測並且在後端運行程式。一開始使用的方法是在 AndroidManifest.xml 加入<category android:name=”android.intent.category.HOME”/> 這個 category 的意思是說當按下 Home 鍵就會執行 Application 的開啟。

<activity 
    android:name="hypro.btLogger.MainActivity" 
    android:label="@string/app_name" 
    android:theme="@style/Theme.AppCompat.Light.NoActionBar" 
    android:screenOrientation="unspecified"> 
    <intent-filter> 
        <action android:name="android.intent.action.MAIN"/> 
        <category android:name="android.intent.category.HOME"/> 
        <category android:name="android.intent.category.DEFAULT"/> 
        <category android:name="android.intent.category.LAUNCHER"/> 
    </intent-filter> 
</activity>

這個方法可適用在某一些單一目的的嵌入式系統,例如 Google 開發的 Android Thing,如果裝置只是被設計出來執行某個特定的 APP 的話,這是一個不錯的解決方法,但是如果裝置上面還要跑其他的應用程式的話,這就不能當作解決方法,所以我們會需要用到 BroadcastReceiver 這一個類別。

首先一樣我們需要修改 AndroidManifest.xml 裡面,主要是在裡面增加一個授權

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

如此一來程式就能夠在開機的時候收到一個 Broadcast 告知我們裝置已經開啟了,而接下來我們只是需要宣告一個 StartBroadcastReceiver 繼承 BroadcastReceiver 來反應當收到開機 intent 時候應該要做的事情,以下列出要執行 Activity 或是 Service 的範例。

public class StartBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){    
            ## Execute Activity
            Intent intent1 = new Intent(context , MainActivity.class);
            intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent1);
            ## Execute Service
            Intent intent2 = new Intent(context , MyService.class);
            context.startService(intent2);
        }
    }
}

接收器會收到廣播(onReceive),並執行你想做的事情。有一點要特別注意,onReceive的生命週期大約只有十秒,超過會產生ANR,因此不要在這邊做太複雜的事情,可以啟動一個Service後,靠Service去執行一些較花時間的動作。詳細 ANR 可以參考連結