Android:多次调用AlarmManager设置闹钟仅首个生效,求原因
嘿,这个问题我太熟了——核心问题出在PendingIntent的唯一性上!
先看你代码里的这行关键代码:
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0 , intent, 0);
每次创建PendingIntent时,你传入的第二个参数requestCode都是0。在Android系统的规则里:如果两个PendingIntent的requestCode相同,并且对应的Intent的核心匹配信息(比如目标组件、Action等)完全一致,系统会把它们当成同一个PendingIntent。这时候你后续调用AlarmManager.set(),本质上是用新的闹钟时间去覆盖旧的那个,而不是创建新的闹钟任务。
你说调用alarm(10); alarm(50);后只有10秒的闹钟触发,这是因为当你快速连续调用这两个方法时,第二个alarm(50)的操作其实是试图替换第一个10秒的闹钟,但因为第一个闹钟的触发时间更早,系统已经开始处理它的触发逻辑,导致替换操作没生效;或者更准确地说,当第一个闹钟触发后,对应的PendingIntent任务被系统清除,第二个原本要替换的闹钟自然也就没了踪影。
怎么解决?
只要让每个闹钟对应的PendingIntent是唯一的就行,有两种简单的实现方式:
1. 给每个PendingIntent分配不同的requestCode
你可以修改alarm方法,新增一个requestCode参数,每次调用时传入不同的数值(比如递增的数字、时间戳,甚至直接用time值,只要保证唯一就行):
public void alarm(int time, int requestCode){ Intent intent = new Intent(MainActivity.this, Alarm.class); AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); // 推荐使用FLAG_UPDATE_CURRENT,确保Intent更新时PendingIntent也同步 PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + time * 1000, pi); }
调用的时候传入不同的requestCode:
alarm(10, 1); alarm(50, 2);
2. 给Intent添加唯一的Extra标识
如果不想修改方法参数,也可以给每个Intent添加一个唯一的额外信息,比如把time或者随机数作为Extra,这样系统会认为这是不同的Intent,从而创建独立的PendingIntent:
public void alarm(int time){ Intent intent = new Intent(MainActivity.this, Alarm.class); // 添加唯一标识,让系统区分不同的Intent intent.putExtra("UNIQUE_ALARM_TAG", time); AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + time * 1000, pi); }
这样即使requestCode都是0,系统也会因为Intent的Extra不同,判定为不同的PendingIntent,每个闹钟任务都会独立存在,不会互相覆盖。
内容的提问来源于stack exchange,提问作者shariful islam

