1. ホーム
  2. android

[解決済み] AlarmManagerで設定したAlarmClockのアラームを、時計アプリで正しくキャンセルする方法を教えてください。

2022-02-17 21:45:36

質問内容

この質問にはすでに回答があります こちら , こちら そして こちら . しかし、それらはOPで動作確認されておらず、私の場合、同じPendingIntentで設定したアラームがキャンセルされないのです。 AlarmClockのアラームをキャンセルする方法はありますか?

@Override
protected void onHandleIntent(@Nullable Intent i) {
    Intent i = new Intent(AlarmClock.ACTION_SET_ALARM);
    i.putExtra(AlarmClock.EXTRA_SKIP_UI, true);
    i.putExtra(AlarmClock.EXTRA_HOUR, 6);
    i.putExtra(AlarmClock.EXTRA_MINUTES, 0);
    i.putExtra(AlarmClock.EXTRA_MESSAGE, "Good Morning");
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    AlarmManager alarmMgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
    PendingIntent alarmIntent = PendingIntent.getActivity(
                    this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
    alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                SystemClock.elapsedRealtime(),
                alarmIntent);
    Log.d(TAG, "Alarm set");

    try {
        Thread.sleep(15000);
        alarmMgr.cancel(alarmIntent);
        Log.i(TAG, "Alarm canceled");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

このコードは期待通りに出力されます。

Alarm set
Alarm canceled

しかし、設定されているアラームを解除することはできません。何が間違っているのでしょうか?

解決方法を教えてください。

ということで、必要なことがわかりました。 使用 ACTION_DISMISS_ALARM の代わりに ACTION_SET_ALARM . 目覚まし時計にすでに設定されているアラームをキャンセルすることができます。

回答 ここで , こちら そして こちら はPendingIntentをキャンセルすることを提案しましたが、私にはうまくいきませんでしたし、質問者にもうまくいくことが確認されていません。

AlarmManagerからPendingIntentをキャンセルしてもうまくいかない理由は、PendingIntentは後で何かをしたり、インテントを送ったりするためにある、ということが考えられると思います。一度やってしまったこと(すでにインテントを送ってしまったこと)は、元に戻すことはできません。例えば、通知をキャンセルすることはできても、通知からアプリを開くこと(実行したインテントやアクション)は、すでに実行されているので、取り消すことはできないのです。しかも、私の場合、アラームの設定を解除する必要があったのは別のアプリだったので、そのアクションを元に戻せると思ってはいけなかったかもしれません。 ですから、アラームを解除したり取り消したりするためには、次のようなアクションを持つ新しいインテントを送信する必要があります。 ACTION_DISMISS_ALARM .

try/catchブロックを以下のように置き換えると、私の場合、アラームの設定とキャンセルが正しく行われます。

try {
    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
        return;
    }
    Thread.sleep(15000);
    Intent ci = new Intent(AlarmClock.ACTION_DISMISS_ALARM);
    ci.setData(i.getData());
    alarmIntent = PendingIntent.getActivity(this, 0, ci, 0);
    alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                SystemClock.elapsedRealtime(),
                alarmIntent);
    Log.i(TAG, "Alarm cancelled");
} catch (InterruptedException e) {
    e.printStackTrace();
}

ただし、これはAPIレベル23以上の場合のみ有効です。 のようにSKIP_UIすることができません。 ACTION_SET_ALARM .