スケジュール管理系のアプリをはじめとして、特定の日時にステータスバーに通知を表示したいという場面があると思います。
今回はその実装方法を紹介します。
処理は以下のような流れになります。
- 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を指定しましょう。
以上です。