Android的警报管理器错误的时期
Android's alarm manager wrong period
我正在为我的应用程序创建 AlarmManager,以便在不同时期发送短信。例如,当我为 AlarmManager 设置 5 分钟的时间时,它几乎立即唤醒大约 1-2 次,但在此之后它工作正常。在我改变 period 的值之后,情况会重复。我认为停止 AlarmManager 或设置中继器有问题。
这是我的 makeAlarm
函数:
private void makeAlarm() {
cancelAlarm();
Intent i = new Intent(this, SmsAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), SmsAlarmReceiver.REQUEST_CODE,
i, PendingIntent.FLAG_UPDATE_CURRENT);
long firstMillis = System.currentTimeMillis();
SharedPreferences refreshSettings = getSharedPreferences("com.example.xd720p.sensorcontroller_09082016",
Context.MODE_PRIVATE);
double refreshForTValue = Double.valueOf(refreshSettings.getString("tempPeriod", "30"));
if (refreshForTValue <= 0 ) {
cancelAlarm();
} else {
long period = Math.round(refreshForTValue * 60 * 1000);
AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, firstMillis,
firstMillis + period, pendingIntent);
}
}
这是我的 cancelAlarm
函数:
private void cancelAlarm() {
try {
Intent i = new Intent(this, SmsAlarmReceiver.class);
PendingIntent pIntent = PendingIntent.getBroadcast(this.getApplicationContext(), SmsAlarmReceiver.REQUEST_CODE,
i, 0);
AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
alarm.cancel(pIntent);
pIntent.cancel();
} catch (Exception e) {
e.printStackTrace();
}
}
这是我的 SmsAlarmReceiver
class 扩展 BroadcastReceiver
:
public class SmsAlarmReceiver extends BroadcastReceiver {
public static final int REQUEST_CODE = 322;
@Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, SmsSenderService.class);
context.startService(i);
}
}
我在 MainActivity
的 onCreate
方法中创建了我的闹钟。当我更改周期值时,我也会停止闹钟并制作新的。此值存储在 SharedPreferences
中,因此我尝试在 onSharedPreferenceChanged
中重新创建警报,但在我的情况下它没有任何意义。
我终于解决了!这是我在 makeAlarm()
函数中的解决方案:
private void makeAlarm() {
cancelAlarm();
Intent i = new Intent(this, SmsAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), SmsAlarmReceiver.REQUEST_CODE,
i, PendingIntent.FLAG_CANCEL_CURRENT);
SharedPreferences refreshSettings = getSharedPreferences("com.example.xd720p.sensorcontroller_09082016",
Context.MODE_PRIVATE);
double refreshForTValue = 0;
refreshForTValue = Double.valueOf(refreshSettings.getString("tempPeriod", "30"));
if (refreshForTValue <= 0 ) {
cancelAlarm();
} else {
long period = Math.round(refreshForTValue * 60 * 1000);
AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
long firstMillis = System.currentTimeMillis();
alarm.setRepeating(AlarmManager.RTC_WAKEUP, firstMillis + period,
period, pendingIntent);
}
}
如您所见,我更改了 setRepeating()
个参数。问题是第二个参数不仅用于设置周期的开始时间,而且它在开始时间唤醒警报。所以如果我们不想立即唤醒闹钟,我们需要添加period值。而第三个参数只是一个重复周期,所以我们需要去掉开始时间。您可以在此处的示例中阅读相关内容:
https://developer.android.com/training/scheduling/alarms.html
在 PendingIntent.getBroadcast()
中,我们需要将标志从 FLAG_UPDATE_CURRENT 更改为 FLAG_CANCEL_CURRENT。我无法准确解释原因,但根据文档,当我们设置 UPDATE 标志时,一些更改的属性将被忽略。因此闹钟会在一个旧时期首先醒来。但是 CANCEL_FLAG 允许我们替换属性并用新的周期唤醒警报。如果我的解释不正确,我很抱歉:正如我所说,我此刻并不完全理解。如果有人给出好的解释,我会很高兴。
我正在为我的应用程序创建 AlarmManager,以便在不同时期发送短信。例如,当我为 AlarmManager 设置 5 分钟的时间时,它几乎立即唤醒大约 1-2 次,但在此之后它工作正常。在我改变 period 的值之后,情况会重复。我认为停止 AlarmManager 或设置中继器有问题。
这是我的 makeAlarm
函数:
private void makeAlarm() {
cancelAlarm();
Intent i = new Intent(this, SmsAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), SmsAlarmReceiver.REQUEST_CODE,
i, PendingIntent.FLAG_UPDATE_CURRENT);
long firstMillis = System.currentTimeMillis();
SharedPreferences refreshSettings = getSharedPreferences("com.example.xd720p.sensorcontroller_09082016",
Context.MODE_PRIVATE);
double refreshForTValue = Double.valueOf(refreshSettings.getString("tempPeriod", "30"));
if (refreshForTValue <= 0 ) {
cancelAlarm();
} else {
long period = Math.round(refreshForTValue * 60 * 1000);
AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, firstMillis,
firstMillis + period, pendingIntent);
}
}
这是我的 cancelAlarm
函数:
private void cancelAlarm() {
try {
Intent i = new Intent(this, SmsAlarmReceiver.class);
PendingIntent pIntent = PendingIntent.getBroadcast(this.getApplicationContext(), SmsAlarmReceiver.REQUEST_CODE,
i, 0);
AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
alarm.cancel(pIntent);
pIntent.cancel();
} catch (Exception e) {
e.printStackTrace();
}
}
这是我的 SmsAlarmReceiver
class 扩展 BroadcastReceiver
:
public class SmsAlarmReceiver extends BroadcastReceiver {
public static final int REQUEST_CODE = 322;
@Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, SmsSenderService.class);
context.startService(i);
}
}
我在 MainActivity
的 onCreate
方法中创建了我的闹钟。当我更改周期值时,我也会停止闹钟并制作新的。此值存储在 SharedPreferences
中,因此我尝试在 onSharedPreferenceChanged
中重新创建警报,但在我的情况下它没有任何意义。
我终于解决了!这是我在 makeAlarm()
函数中的解决方案:
private void makeAlarm() {
cancelAlarm();
Intent i = new Intent(this, SmsAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), SmsAlarmReceiver.REQUEST_CODE,
i, PendingIntent.FLAG_CANCEL_CURRENT);
SharedPreferences refreshSettings = getSharedPreferences("com.example.xd720p.sensorcontroller_09082016",
Context.MODE_PRIVATE);
double refreshForTValue = 0;
refreshForTValue = Double.valueOf(refreshSettings.getString("tempPeriod", "30"));
if (refreshForTValue <= 0 ) {
cancelAlarm();
} else {
long period = Math.round(refreshForTValue * 60 * 1000);
AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
long firstMillis = System.currentTimeMillis();
alarm.setRepeating(AlarmManager.RTC_WAKEUP, firstMillis + period,
period, pendingIntent);
}
}
如您所见,我更改了
setRepeating()
个参数。问题是第二个参数不仅用于设置周期的开始时间,而且它在开始时间唤醒警报。所以如果我们不想立即唤醒闹钟,我们需要添加period值。而第三个参数只是一个重复周期,所以我们需要去掉开始时间。您可以在此处的示例中阅读相关内容: https://developer.android.com/training/scheduling/alarms.html在
PendingIntent.getBroadcast()
中,我们需要将标志从 FLAG_UPDATE_CURRENT 更改为 FLAG_CANCEL_CURRENT。我无法准确解释原因,但根据文档,当我们设置 UPDATE 标志时,一些更改的属性将被忽略。因此闹钟会在一个旧时期首先醒来。但是 CANCEL_FLAG 允许我们替换属性并用新的周期唤醒警报。如果我的解释不正确,我很抱歉:正如我所说,我此刻并不完全理解。如果有人给出好的解释,我会很高兴。