2017.05.31
Android 指定した日時に通知(Notification)を送る
スケジュール管理系のアプリをはじめとして、特定の日時にステータスバーに通知を表示したいという場面があると思います。
今回はその実装方法を紹介します。
処理は以下のような流れになります。
- AlarmManagerを用いてIntentを登録しておく
- 指定した時間が来るとシステムがIntentをBroadcastする
- BroadcastReceiverでIntentを受け取り通知(Notification)を発行する
まずはReceiver側の実装を見ていきます。
public class AlarmReceiver extends BroadcastReceiver { public static String NOTIFICATION_ID = "notificationId"; public static String NOTIFICATION_CONTENT = "content"; @Override public void onReceive(Context context, Intent intent) { NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); int id = intent.getIntExtra(NOTIFICATION_ID, 0); String content = intent.getStringExtra(NOTIFICATION_CONTENT); notificationManager.notify(id, buildNotification(context, content)); } private Notification buildNotification(Context context, String content) { Notification.Builder builder = new Notification.Builder(context); builder.setContentTitle("Notification!!") .setContentText(content) .setSmallIcon(android.R.drawable.sym_def_app_icon); return builder.build(); } }
Receiverの役割はIntentを受け取り、NotificationManagerを用いて通知を送ることです。
後ほどIntentに通知のidと通知に表示する内容を詰めて渡すので、それを取り出して用いています。
今回はMainActivityで通知の内容の決定と送るタイミングをスケジュールします。
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.schedule_button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.add(Calendar.SECOND, 10); scheduleNotification("10秒後に届く通知です", calendar); } }); } private void scheduleNotification(String content, Calendar calendar){ Intent notificationIntent = new Intent(this, AlarmReceiver.class); notificationIntent.putExtra(AlarmReceiver.NOTIFICATION_ID, 1); notificationIntent.putExtra(AlarmReceiver.NOTIFICATION_CONTENT, content); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE); alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent); } }
今回のサンプルではボタンを押すと、現在の時刻から10秒後に通知が届きます。
scheduleNotificationの第二引数には通知を送りたい日時のCalendarオブジェクトを渡します。
AlarmManager.setExactの第一引数では今回AlarmManager.RTC_WAKEUPフラグを指定しています。
これは端末の時刻が指定した時刻に到達したタイミングでIntentを飛ばします。また、端末がスリープ状態のときは起動します。スリープからの復帰が不要なときはAlarmManager.RTCを指定しましょう。
以上です。