AlarmManager不会取消闹钟

时间:2016-01-01 04:57:08

标签: android android-intent android-pendingintent repeatingalarm

由于我可能需要解释为什么我的问题之前没有得到解答,所以我遇到的帖子都没有给我一个线索,说明为什么我的代码不起作用。我从那些帖子中采用了这个代码。

这是目标:当我设置闹钟时,我需要先取消已设置的闹钟。这是我正在使用的代码:

public void startAlarm(View view) {
    //setup
    EditText nameInput = (EditText) this.findViewById(R.id.nameInput);
    EditText firstAlertInput = (EditText) this.findViewById(R.id.firstAlertInput);
    EditText intervalInput = (EditText) this.findViewById(R.id.intervalInput);
    EditText descriptionInput = (EditText) this.findViewById(R.id.descriptionInput);
    SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
    SharedPreferences.Editor editor = sp.edit();
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

    //Cancels the current alarm
    Intent tempIntent = new Intent(this, AlarmReciever.class);
    tempIntent.putExtra("name", sp.getString("oldName", ""));
    tempIntent.putExtra("description", sp.getString("oldDescription", ""));
    Log.d("test", tempIntent.getStringExtra("name"));
    Log.d("test", tempIntent.getStringExtra("description"));
    PendingIntent tempPendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 234324243, tempIntent, 0);
    alarmManager.cancel(tempPendingIntent);

    //Creates new alarm structure
    Intent intent = new Intent(this, AlarmReciever.class);
    intent.putExtra("name", nameInput.getText().toString());
    intent.putExtra("description", descriptionInput.getText().toString());
    Log.d("test", intent.getStringExtra("name"));
    Log.d("test", intent.getStringExtra("description"));

    PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 234324243, intent, 0);

    //Stores old details
    editor.putString("oldName", nameInput.getText().toString());
    editor.putString("oldDescription", descriptionInput.getText().toString());
    editor.apply();

    //Finishes new alarm details
    int[] times = parseTime(firstAlertInput.getText().toString());
    times[0] = times[0] * 3600000;
    times[1] = times[1] * 60000;
    long millis = times[0] + times[1];
    int[] intervalTimes = parseTime(intervalInput.getText().toString());
    intervalTimes[0] = intervalTimes[0] * 3600000;
    intervalTimes[1] = intervalTimes[1] * 60000;
    long intervalMillis = intervalTimes[0] + intervalTimes[1];

    //New alarm set
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + millis, intervalMillis, pendingIntent);
}

private int[] parseTime(String input){
    int[] times = new int[2];
    String[] split = input.split(":");
    for(int i = 0; i < times.length; i++){
        times[i] = Integer.parseInt(split[i]);
    }
    return times;
}

问题在于:当手机重新启动并且应用程序正在运行后设置第一个警报时,它会像平常一样运行。设置的所有后续警报未成功设置,并且首先设置的警报继续不受影响。即使我将警报重置四次,第一次警报仍继续运行,新警报未设置。

编辑:请阅读本文对测试环境和版本的评论。

1 个答案:

答案 0 :(得分:0)

您正在观察的问题是系统管理PendingIntents的方式的结果。 PendingIntent的概述中解释了这一点:

  

人们常犯的错误是创建多个PendingIntent   具有Intent的对象只有在&#34; extra&#34;内容,   期望每次获得不同的PendingIntent。事实并非如此   发生。用于匹配的Intent部分是   由Intent.filterEquals定义的相同内容。如果你使用两个Intent   根据Intent.filterEquals等效的对象,那么你会   为他们两个获得相同的PendingIntent。

在您的情况下,获取pendingIntent的调用将返回先前的意图,而不是创建新的PendingIntent。您可以通过将标记PendingIntent.FLAG_UPDATE_CURRENT添加到PendingIntent.getBroadcast的调用中来解决此问题。

您可以通过删除语句来取消现有警报,从而进一步简化代码。如文档中所述,拨打setRepeating()将取消已为同一PendingIntent设置的任何警报。