AlarmService を利用したサービス実行のスケジューリング

例えば「一日に一度朝 5 時にニュースをチェックする」というような処理を行うには、システムのアラームサービスを利用すると良いです。

Windows でいうところのタスクスケジューラなどに相当すると考えるとわかりやすいかもしれません。

ここではアラームサービスを利用して、サービスを実行する方法を説明します。

アラームサービスとは?

Android システムにはアラームサービスというスケジューラがあり、これは AlarmManager を利用して設定することができます。

アラームサービスを利用すると、何時にプログラムを起動する、とか、何分おき、何時間おきにプログラムをバックグラウンドで実行するというようなことが実現できます。

スケジュールの方法

アラームサービスの利用方法は次のような流れになります。

  1. サービスを起動するインテント (Intent) の作成
  2. スケジュールされたタイミングでサービスを起動するための、ペンディングインテント (PendingIntent) を作成する
  3. アラームマネージャ (AlarmManager) から繰り返し処理を設定する

ペンディングインテントを作成する時のフラグは次のようなものがあります。

フラグ意味
FLAG_CANCEL_CURRENT現在設定されているものがあれば、それをキャンセルして新しい設定を行う。
FLAG_NO_CREATE存在していなければ、単に null を返す。(新規に作成しない)
FLAG_ONE_SHOT一度だけ利用できる
FLAG_UPDATE_CURRENT存在していればそれを使う。新しい設定で置き換えない。

実行間隔、設定値の意味などの設定に関するパラメータは次の通りです。

定数意味
ELAPSED_REALTIMESystemClock.elapsedRealtime() によるアラーム時間 (スリープを含む起動してからの時間)
ELAPSED_REALTIME_WAKEUPELAPSED_REALTIME と同様だが、スリープしている時は起きる
INTERVAL_DAY一日間隔
INTERVAL_FIFTEEN_MINUTES15分間隔
INTERVAL_HALF_DAY半日間隔
INTERVAL_HALF_HOUR30分間隔
INTERVAL_HOUR一時間間隔
RTCSystem.currentTimeMillis() によるアラーム時間 (UTC)
RTC_WAKEUPRTC と同様だが、スリープしている時は起きる

スケジュールのキャンセル方法

スケジュールを取り消す場合は、アラームマネージャの 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" をおすとスケジュールされた処理がキャンセルされます。ここではログが記録されなくなることで、キャンセルされたことが確認できます。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Android 開発入門