具体的には、まず、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() // 最後に端末がスリープ状態に戻れるようにする。 } }