具体的には、まず、AlarmManagerを使用して、定期的にBroadcastのIntentを投げる。AlarmManager.RTC_WAKEUPを指定して、端末がスリープ中でもBroadcastが行われるようにしておく。
public class Foo {
private static final long INTERVAL = AlarmManager.INTERVAL_FIFTEEN_MINUTES;
public void setBroadcast() {
Intent intent = new Intent(this, BarReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), INTERVAL, pendingIntent);
}
}
次に、BroadcastReceiverを継承したクラスで、BroadcastのIntentを受け取るようにする。端末がスリープ状態だった場合、onReceiveを抜けると、端末が再びスリープ状態に戻るのが仕様なので、 PowerManager.WakeLock#acquier() で、端末がスリープ状態に移行しないようにしておく。(BarReceiverのインスタンスよりも長い期間存在する必要があるので、static変数にしてある) そして、バックグラウンド処理を実行するサービスを起動する。
public class BarReceiver extends BroadcastReceiver {
private static PowerManager.WakeLock wl;
@Override
public void onReceive(Context context, Intent arg1) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "BarReceiver");
wl.acquire();
Intent intent = new Intent(context, BazService.class);
context.startService(intent);
}
public static void releaseWakeLock() {
if (wl != null) {
wl.release();
}
}
}
サービスでは、バックグラウンド処理を実行し、最後にPowerManager.WakeLock#release()が実行されるようにして、端末が再びスリープ状態に戻れるようにしておく。
public class BazService extends Service {
@Override
public void onCreate() {
new Thread(new BazProcess())
.start();
}
private class BazProcess implements Runnable {
@Override
public void run() {
// ここでバックグラウンド処理を実行。
BarReceiver.releaseWakeLock() // 最後に端末がスリープ状態に戻れるようにする。
}
}