[ Android ] AlarmManagerを使おう

目覚まし時計用にAlarmManagerを利用してみる

・Android 7.1.1

参考にココが見やすいです

ある時間にアプリから通知して欲しいという場合がよくあります。目覚まし時計とかスケジュール系のアプリなど、これらの通知には時間を管理する AlarmManager 及びその関連APIを使います。  

1.適当にプロジェクト作成
いつも通りEmpty Activityとかにしておく

2.activity_main.xml にボタン追加

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button_set"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

</android.support.constraint.ConstraintLayout>

3.MainActivityにコードを追加

ボタン押したらセットするように。例では5秒後に発火。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    findViewById(R.id.button_set).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(System.currentTimeMillis());
            calendar.add(Calendar.SECOND, 5);

            Intent intent = new Intent(getApplicationContext(), AlarmBroadcastReceiver.class);
            PendingIntent pending = PendingIntent.getBroadcast(
                    getApplicationContext(),
                    0,
                    intent,
                    PendingIntent.FLAG_UPDATE_CURRENT);

            AlarmManager manager = (AlarmManager)getSystemService(ALARM_SERVICE);
            if (manager != null) {
                Log.d("test", "manager.setExact");
                manager.setAlarmClock(new AlarmManager.AlarmClockInfo(calendar.getTimeInMillis(), null), pending);
                Toast.makeText(getApplicationContext(), "Set Alarm", Toast.LENGTH_SHORT).show();
            }
        }
    });
}

AlarmManagerのsetはバージョンでいろいろ変わってるので、端末のバージョンを考える必要があります。

setAlarmClockを使うとステータスバーに時計マークが出ます。

setExtraでも同等のことが可能

4.Receiverの作成

アラームのセット時に渡すIntentの受け口

AlarmBroadcastReceiver.java

public class AlarmBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "AlarmBroadcastReceiver onReceive", Toast.LENGTH_SHORT).show();
    }
}

AndroidManifest.xml

<receiver android:name=".alarm.AlarmBroadcastReceiver" />

5.Sleepの対応

端末の電源ボタン押すとスリープ状態になって動作してるか判らないので、画面を起こしてみる。手順は色々あると思うけど単純に出来そうなもので。

AlarmBroadcastReceiver.java に追記

    @Override
    public void onReceive(Context context, Intent intent) {
        PowerManager powerManager = (PowerManager)context.getSystemService(POWER_SERVICE);
        PowerManager.WakeLock wakeLock = powerManager.newWakeLock(
                PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
                "MyWakelookTag");
        wakeLock.acquire();
        wakeLock.release();

        Toast.makeText(context, "AlarmBroadcastReceiver onReceive", Toast.LENGTH_SHORT).show();
    }

AndroidManifest.xml にパーミッション追加

<uses-permission android:name="android.permission.WAKE_LOCK" />

PowerManagerを利用していますが、PowerManager.SCREEN_BRIGHT_WAKE_LOCK は非推奨になってます。