sos の 作業メモ

プログラミングや英会話学習、マイルや旅行、日常生活など。最近はWebFormなASP.NETのお守りがお仕事です。

日々の生活にhappyをプラスする|ハピタス Gポイント

Tips: Androidでブート完了時にアプリを自動起動したり、充電開始で動作を変えたりする方法

とてもいまさらなネタですが、電源を投入した時に自動で起動するタイプのアプリを作ったのは初めてなので記録に残しときます。

自動起動

処理は簡単で、ブートが完了したときにシステムから

Intent.ACTION_BOOT_COMPLETED

というのがBroadcastされますので、それをBroadcastReceiverで捕まえて、自分自身をIntentするだけ。ついでにアプリがアップデートされた際にも起動してくれると嬉しいかもしれないので、

Intent.ACTION_PACKAGE_REPLACED

もつかまえるReceiverにします。

public class BootedReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        if (intent != null) {
            boolean execute = false;
            if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
                execute = true;
            } else if (Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction()) && intent.getDataString().contains(context.getPackageName())) {
                execute = true;
            }
            if (execute) {
                Intent i = new Intent(context, MainActivity.class);
                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(i);
            }
        }
    }
}

あとは、AndroidManifest.xmlの中でこのBroadcastReceiverを設定して、

    <receiver
            android:name=".BootedReceiver"
            android:permission="android.permission.RECEIVE_BOOT_COMPLETED"
            >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.PACKAGE_REPLACED"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </receiver>

パーミッションの使用を宣言しておくだけです。

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

充電開始を捕まえる

これも充電開始/停止やバッテリーの残量が変化した時に

Intent.ACTION_BATTERY_CHANGED
Intent.ACTION_POWER_CONNECTED
Intent.ACTION_POWER_DISCONNECTED

がBroadcastされるので、これを捕まえるReceiverを書いて処理するだけ。

こいつらはAndroidManifest.xmlではなく、コードの中で直接filterを定義してやるべきものの類。 (BATTERY_CANGEDとかはマニフェストに書いても無効だったような気もします)

AndroidManifest.xmlにだと、アプリが起動していない時でもReceiverが起動してややこしいですしね。

private BroadcastReceiver mPowerConnectedReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(Intent.ACTION_POWER_CONNECTED.equals(intent.getAction())){
            // 充電開始(ほんとは外部からの電源供給開始)したので何か処理を行う                                
        }
    }
};

そんなわけで無名クラスとしてインスタンスを作り、ActivityのonResumeあたりで

// ACTION_POWER_CONNECTEDの捕捉を開始
registerReceiver(mPowerConnectedReceiver, new IntentFilter(Intent.ACTION_POWER_CONNECTED));

onPauseあたりで

unregisterReceiver(mPowerConnectedReceiver);

すればばっちりです。