AlarmManager 延迟触发或根本不触发
AlarmManager fires late or doesn't fire at all
大家好,我正在尝试学习如何在 Android 中使用 AlarmManager
和 BroadcastReceiver
。
AlarmManager
我遇到了一些问题:
我在 1 分钟的距离设置了两个警报,但只有一个触发,而且晚了几分钟(我猜无法预测)。
这是我的主要 activity(我通过点击按钮设置闹钟)
public class MainActivity extends AppCompatActivity {
AlarmManager alarmManager;
Intent intent;
PendingIntent pendingIntent;
AtomicInteger atomicInteger;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
intent = new Intent(Constants.EXTENDED_DATA_STATUS);
atomicInteger = new AtomicInteger();
setContentView(R.layout.activity_main);
Button startButton = (Button) findViewById(R.id.start_button);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int id = atomicInteger.incrementAndGet();
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),id,intent,0);
Calendar firstLullo = Calendar.getInstance();
Calendar secondLullo = Calendar.getInstance();
firstLullo.set(Calendar.HOUR_OF_DAY,10);
firstLullo.set(Calendar.MINUTE,55);
secondLullo.set(Calendar.HOUR_OF_DAY,10);
secondLullo.set(Calendar.MINUTE,56);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP,firstLullo.getTimeInMillis(),pendingIntent);
alarmManager.setExact(AlarmManager.RTC_WAKEUP,secondLullo.getTimeInMillis(),pendingIntent);
}
Log.d("ALARM","settato con id " + String.valueOf(id));
}
});
}
}
我的接收器只是显示一个 Toast 并使 phone 振动。
Constants.EXTENDED_DATA_STATUS
是来自 Constants
class 的字符串,它被添加到 Android Manifest 中我 Receiver 的 intent-filter
。
我错过了什么?我在谷歌上搜索了很多,只发现我必须使用 setExact()
但没有运气..
提前致谢
只有一个触发的原因是因为你取消你的第一个总是
From the docs: If there is already an alarm scheduled for the same IntentSender, that previous alarm will first be canceled.
要解决此问题,请对两个警报使用不同的 PendingIntents。
- 要让您的接收器发射 多次 次,请在您的 onReceive()
中重新安排
示例:
仅当您希望两个接收器彼此分开时!
//Declare AlarmManager
AlarmManager am = (AlarmManager) LayoutActivity.this.getSystemService(ALARM_SERVICE);
//create new calendar instance for your first alarm
Calendar startTime= Calendar.getInstance();
//set the time of your first alarm
firstLullo.set(Calendar.HOUR_OF_DAY,10);
firstLullo.set(Calendar.MINUTE, 55);
firstLullo.set(Calendar.SECOND, 0);
//create a pending intent
PendingIntent firstPI = PendingIntent.getBroadcast(yourActivity.this, 0, new Intent("yourFirstAlarmReceiver"), PendingIntent.FLAG_UPDATE_CURRENT);
//schedule time for pending intent, and set the interval to day so that this event will repeat at the selected time every day
am.setRepeating(AlarmManager.RTC_WAKEUP, firstAlarm.getTimeInMillis(), firstPI);
//----------------------------------------------------
//create new calendar instance for your second alarm
Calendar endCalender = Calendar.getInstance();
//Set the time alarm of your second alarm
secondLullo.set(Calendar.HOUR_OF_DAY,10);
secondLullo.set(Calendar.MINUTE,56);
secondLullo.set(Calendar.SECOND, 0);
//create a pending intent to be
PendingIntent secondPI= PendingIntent.getBroadcast(yourActivity.this, 0, new Intent("yourSecondAlarmReceiver"), PendingIntent.FLAG_UPDATE_CURRENT);
//schedule time for pending intent, and set the interval to day so that this event will repeat at the selected time every day
am.setRepeating(AlarmManager.RTC_WAKEUP, secondLullo.getTimeInMillis(), secondPI);
在Manifest.XML中注册闹钟:
<receiver android:name="firstAlarm" >
<intent-filter>
<action android:name="yourFirstAlarmReceiver" >
</action>
</intent-filter>
</receiver>
<receiver android:name="secondAlarm" >
<intent-filter>
<action android:name="yourSecondAlarmReceiver" >
</action>
</intent-filter>
</receiver>
现在您可以通过以下方式拨打闹钟:
第一个警报:
public class yourFirstAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Do something when first alarm goes off
}
}
第二个警报:
public class yourSecondAlarmReceiverextends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Do something when second alarm goes off
}
}
应该能帮到你。
是的,当然上面的代码只会触发一个警报,因为您为两个警报设置了相同的 ID。
通过 pendingintent 中的 id 标识和区分警报。
不同的闹钟使用不同的id
更新代码:
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1234 ,intent,0);
alarmManager.setExact(AlarmManager.RTC_WAKEUP,firstLullo.getTimeInMillis(),pendingIntent);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 5678, intent,0);
alarmManager.setExact(AlarmManager.RTC_WAKEUP,secondLullo.getTimeInMillis(),pendingIntent);
大家好,我正在尝试学习如何在 Android 中使用 AlarmManager
和 BroadcastReceiver
。
AlarmManager
我遇到了一些问题:
我在 1 分钟的距离设置了两个警报,但只有一个触发,而且晚了几分钟(我猜无法预测)。
这是我的主要 activity(我通过点击按钮设置闹钟)
public class MainActivity extends AppCompatActivity {
AlarmManager alarmManager;
Intent intent;
PendingIntent pendingIntent;
AtomicInteger atomicInteger;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
intent = new Intent(Constants.EXTENDED_DATA_STATUS);
atomicInteger = new AtomicInteger();
setContentView(R.layout.activity_main);
Button startButton = (Button) findViewById(R.id.start_button);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int id = atomicInteger.incrementAndGet();
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),id,intent,0);
Calendar firstLullo = Calendar.getInstance();
Calendar secondLullo = Calendar.getInstance();
firstLullo.set(Calendar.HOUR_OF_DAY,10);
firstLullo.set(Calendar.MINUTE,55);
secondLullo.set(Calendar.HOUR_OF_DAY,10);
secondLullo.set(Calendar.MINUTE,56);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP,firstLullo.getTimeInMillis(),pendingIntent);
alarmManager.setExact(AlarmManager.RTC_WAKEUP,secondLullo.getTimeInMillis(),pendingIntent);
}
Log.d("ALARM","settato con id " + String.valueOf(id));
}
});
}
}
我的接收器只是显示一个 Toast 并使 phone 振动。
Constants.EXTENDED_DATA_STATUS
是来自 Constants
class 的字符串,它被添加到 Android Manifest 中我 Receiver 的 intent-filter
。
我错过了什么?我在谷歌上搜索了很多,只发现我必须使用 setExact()
但没有运气..
提前致谢
只有一个触发的原因是因为你取消你的第一个总是
From the docs: If there is already an alarm scheduled for the same IntentSender, that previous alarm will first be canceled.
要解决此问题,请对两个警报使用不同的 PendingIntents。
- 要让您的接收器发射 多次 次,请在您的 onReceive()
示例: 仅当您希望两个接收器彼此分开时!
//Declare AlarmManager
AlarmManager am = (AlarmManager) LayoutActivity.this.getSystemService(ALARM_SERVICE);
//create new calendar instance for your first alarm
Calendar startTime= Calendar.getInstance();
//set the time of your first alarm
firstLullo.set(Calendar.HOUR_OF_DAY,10);
firstLullo.set(Calendar.MINUTE, 55);
firstLullo.set(Calendar.SECOND, 0);
//create a pending intent
PendingIntent firstPI = PendingIntent.getBroadcast(yourActivity.this, 0, new Intent("yourFirstAlarmReceiver"), PendingIntent.FLAG_UPDATE_CURRENT);
//schedule time for pending intent, and set the interval to day so that this event will repeat at the selected time every day
am.setRepeating(AlarmManager.RTC_WAKEUP, firstAlarm.getTimeInMillis(), firstPI);
//----------------------------------------------------
//create new calendar instance for your second alarm
Calendar endCalender = Calendar.getInstance();
//Set the time alarm of your second alarm
secondLullo.set(Calendar.HOUR_OF_DAY,10);
secondLullo.set(Calendar.MINUTE,56);
secondLullo.set(Calendar.SECOND, 0);
//create a pending intent to be
PendingIntent secondPI= PendingIntent.getBroadcast(yourActivity.this, 0, new Intent("yourSecondAlarmReceiver"), PendingIntent.FLAG_UPDATE_CURRENT);
//schedule time for pending intent, and set the interval to day so that this event will repeat at the selected time every day
am.setRepeating(AlarmManager.RTC_WAKEUP, secondLullo.getTimeInMillis(), secondPI);
在Manifest.XML中注册闹钟:
<receiver android:name="firstAlarm" >
<intent-filter>
<action android:name="yourFirstAlarmReceiver" >
</action>
</intent-filter>
</receiver>
<receiver android:name="secondAlarm" >
<intent-filter>
<action android:name="yourSecondAlarmReceiver" >
</action>
</intent-filter>
</receiver>
现在您可以通过以下方式拨打闹钟:
第一个警报:
public class yourFirstAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Do something when first alarm goes off
}
}
第二个警报:
public class yourSecondAlarmReceiverextends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Do something when second alarm goes off
}
}
应该能帮到你。
是的,当然上面的代码只会触发一个警报,因为您为两个警报设置了相同的 ID。
通过 pendingintent 中的 id 标识和区分警报。
不同的闹钟使用不同的id
更新代码:
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1234 ,intent,0);
alarmManager.setExact(AlarmManager.RTC_WAKEUP,firstLullo.getTimeInMillis(),pendingIntent);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 5678, intent,0);
alarmManager.setExact(AlarmManager.RTC_WAKEUP,secondLullo.getTimeInMillis(),pendingIntent);