AlarmService を利用したサービス実行のスケジューリング
例えば「一日に一度朝 5 時にニュースをチェックする」というような処理を行うには、システムのアラームサービスを利用すると良いです。
Windows でいうところのタスクスケジューラなどに相当すると考えるとわかりやすいかもしれません。
ここではアラームサービスを利用して、サービスを実行する方法を説明します。
アラームサービスとは?
Android システムにはアラームサービスというスケジューラがあり、これは AlarmManager を利用して設定することができます。
アラームサービスを利用すると、何時にプログラムを起動する、とか、何分おき、何時間おきにプログラムをバックグラウンドで実行するというようなことが実現できます。
スケジュールの方法
アラームサービスの利用方法は次のような流れになります。
- サービスを起動するインテント (Intent) の作成
- スケジュールされたタイミングでサービスを起動するための、ペンディングインテント (PendingIntent) を作成する
- アラームマネージャ (AlarmManager) から繰り返し処理を設定する
ペンディングインテントを作成する時のフラグは次のようなものがあります。
フラグ | 意味 |
---|---|
FLAG_CANCEL_CURRENT | 現在設定されているものがあれば、それをキャンセルして新しい設定を行う。 |
FLAG_NO_CREATE | 存在していなければ、単に null を返す。(新規に作成しない) |
FLAG_ONE_SHOT | 一度だけ利用できる |
FLAG_UPDATE_CURRENT | 存在していればそれを使う。新しい設定で置き換えない。 |
実行間隔、設定値の意味などの設定に関するパラメータは次の通りです。
定数 | 意味 |
---|---|
ELAPSED_REALTIME | SystemClock.elapsedRealtime() によるアラーム時間 (スリープを含む起動してからの時間) |
ELAPSED_REALTIME_WAKEUP | ELAPSED_REALTIME と同様だが、スリープしている時は起きる |
INTERVAL_DAY | 一日間隔 |
INTERVAL_FIFTEEN_MINUTES | 15分間隔 |
INTERVAL_HALF_DAY | 半日間隔 |
INTERVAL_HALF_HOUR | 30分間隔 |
INTERVAL_HOUR | 一時間間隔 |
RTC | System.currentTimeMillis() によるアラーム時間 (UTC) |
RTC_WAKEUP | RTC と同様だが、スリープしている時は起きる |
スケジュールのキャンセル方法
スケジュールを取り消す場合は、アラームマネージャの cancel メソッドに PendingIntent を渡します。 これによって、ここで指定された種類のクラスにマッチするサービスに関わる処理が取り消されます。
アラームサービスによるサービスのスケジュール例
サービス側は特に何も特別なことはありません。ここでは IntentService でサービスを実装しています。
package com.keicode.android.test;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;
public class MyService3 extends IntentService {
final static String TAG = "ServiceTest3";
public MyService3() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
Log.d(TAG, "onHandleIntent");
}
}
見ての通り、ここでは単にログを記録するだけです。
さて、ポイントはスケジュールする側です。AlarmManager を使ってアラームサービスの設定を行う例は次の通りです。
package com.keicode.android.test;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ServiceTest3 extends Activity {
final static String TAG = "ServiceTest3";
Button scheduleButton;
Button cancelButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
scheduleButton = (Button)findViewById(R.id.schedule_button);
scheduleButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
scheduleService();
}
});
cancelButton = (Button)findViewById(R.id.cancel_button);
cancelButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
cancelService();
}
});
}
protected void scheduleService(){
Log.d(TAG, "scheduleService()");
Context context = getBaseContext();
Intent intent = new Intent(context, MyService3.class);
PendingIntent pendingIntent
= PendingIntent.getService(
context, -1, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager
= (AlarmManager)
context.getSystemService(ALARM_SERVICE);
alarmManager.setInexactRepeating(
AlarmManager.RTC,
System.currentTimeMillis(),
5000, pendingIntent);
}
protected void cancelService(){
Context context = getBaseContext();
Intent intent = new Intent(context, MyService3.class);
PendingIntent pendingIntent
= PendingIntent.getService(
context, -1, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager
= (AlarmManager)
context.getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
}
}
また、サービスを利用するので AndroidManifest.xml にサービス名を設定することをお忘れ無く。
上記のプログラムを実行すると次の画面が表示されます。
"Schedule Service" をおすとアラームが設定され、処理が繰り返し実行されます。
"Cancel Scheduled Service" をおすとスケジュールされた処理がキャンセルされます。ここではログが記録されなくなることで、キャンセルされたことが確認できます。