QA@IT

AndroidでAlarmManagerのキャンセル方法

11952 PV

お世話になっております。
Androidでアラーム機能を実装中なのですが、以下のようなバグが発生します。
1.アラームを設定する
2.キャンセルする
3.アラームを再度設定する
4.設定時刻になると、アラームが多重に起動してしまう

2の時点では正しくキャンセルされているようで、設定時刻になってもアラームは動きません。
4の段階で、複数回に渡ってIntentがとんでいるようです。

4の段階で、多重起動をやめて、一度だけアラームが起動するように修正したいと思っています。
登場人物とコードは以下の通りです。
すみませんが、どなたかよろしくお願いします。
APIVersionは10です。

【登場人物】
・AlarmSetActivity
-アラームを設定するアクティビティ(画面からのチェックボックスによってアラーム設定)
・AlarmReceiver
-アラームのレシーバー(BroadcastReceiverを継承)
・AlarmActivity
-アラームを鳴らすActivity。設定時刻になるとアラームのレシーバーからこの画面に遷移してアラームを鳴らす。
【コード】

//アラームを設定するアクティビティ
AlarmSetActivity{
    private AlarmReceiver receiver;
        //アラームを設定
    public void onCheckboxClicked(View v) {
        TimePicker timePicker = (TimePicker) findViewById(R.id.time_picker);
        PendingIntent pi = getPendingIntent();
        AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(
                Context.ALARM_SERVICE);

        if (((CheckBox) v).isChecked()) {
        //チェックボックスがONならアラーム設定する
            alarmManager.set(AlarmManager.RTC_WAKEUP, getStartTime(timePicker),
                    pi);
        } else {
        //チェックボックスがOFFならキャンセルする
            alarmManager.cancel(pi);
            pi.cancel();
            this.unregisterReceiver(receiver);
        }

    }

    private PendingIntent getPendingIntent() {
    //現アクティビティ(AlarmSetActivity)から(AlarmReceiver)へ送信するIntentを設定

        IntentFilter filter = new IntentFilter();
        filter.addAction(Constants.ALARM);
        receiver = new AlarmReceiver();
        registerReceiver(receiver, filter);
        Intent broadcastIntent = new Intent();
        broadcastIntent.setAction(Constants.ALARM);

        return PendingIntent.getBroadcast(getApplicationContext(), 0,
                broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    }

//アラームのレシーバー
public class AlarmReceiver extends BroadcastReceiver {

    boolean alarmSetFlg;

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent transCall = new Intent(context,AlarmActivity.class);
        transCall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(transCall);
        }
}

AndroidManifest.xml

        <receiver
            android:name="jp.exmple.alarm.AlarmReceiver"
            android:permission="android.permission.Alarm"
            android:process=":remote" >
            <intent-filter>
                <action android:name="Alarm" />
            </intent-filter>
        </receiver>

【追記】
onCheckboxClickedメソッドを以下のように書き換えたら解決しました。
まだ整理できると思いますが、取り急ぎ。ありがとうございました。

    public void onCheckboxClicked(View v) {
        TimePicker timePicker = (TimePicker) findViewById(R.id.time_picker);

        if (((CheckBox) v).isChecked()) {
            PendingIntent pi = getPendingIntent();
            AlarmManager alarmManager = (AlarmManager) getApplicationContext()
                    .getSystemService(Context.ALARM_SERVICE);
            alarmManager.set(AlarmManager.RTC_WAKEUP, getStartTime(timePicker),
                    pi);
        } else {
            AlarmManager aManager = (AlarmManager) getSystemService(ALARM_SERVICE);         
            Intent intent = new Intent(getBaseContext(), AlarmReceiver.class);      
            PendingIntent pIntent = PendingIntent.getBroadcast(AlarmSetActivity.this, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);         
            aManager.cancel(pIntent);
//          alarmManager.cancel(pi);
            pIntent.cancel();
            this.unregisterReceiver(receiver);
        }

    }

ウォッチ

この質問への回答やコメントをメールでお知らせします。