在广播接收器中使用 setExact() 重复
Using setExact() in broadcast receiver to repeat
场景:
生产线工人在特定时间间隔进行检查。在我的应用程序中,用户将此时间间隔输入到文本框中。有日期和时间选择器,以便用户可以 select 进程开始的时间。我想在下一次检查到期前 5 分钟发出警报。
例如:
流程从 2.30 开始。用户以 20 分钟为间隔输入。因此,下一次支票将于 2.50 到期。警报应在 2.45 响起。然后将重复此过程,因此下一次检查将是 3.10,警报应在 3.05 响起。
这是我的代码:
MainActivity.calculate();
commencedTime = new Date();
mTime = Calendar.getInstance();
mTime.setTime(alarmTime);
timeCommenced = trimSecsAndMillisecs(mTime).getTimeInMillis();
currentTime = new Date();
currentTime.getTime();
alertDialogBuilder = new AlertDialog.Builder(MainActivity.this);
//set alert
alertDialogBuilder
.setTitle("IP Check frequency: " + time.getText() + " minutes")
.setMessage("Processing commenced at \n" + startTime.getText())
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (currentTime.after(alarmTime)) {
Toast.makeText(MainActivity.this, "Missed first alert", Toast.LENGTH_LONG).show();
}
i = Integer.parseInt(time.getText().toString());
long scTime2 = ((i * 60 * 1000)); //TIME ENTERED IN MILLISECONDS
intent1 = new Intent(MainActivity.this, MyBroadcastReceiver.class);
intent1.putExtra("timeEntered", scTime2);
intent1.putExtra("timeCommenced", timeCommenced);
sendBroadcast(intent1);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
manager.setExact(AlarmManager.RTC_WAKEUP, timeCommenced, pendingIntent);
Toast.makeText(MainActivity.this, "Alert Set", Toast.LENGTH_SHORT).show();
stopped.setVisibility(View.VISIBLE);
commenced1.setVisibility(View.GONE);
//Change editText to TextView
time.setVisibility(View.GONE);
timeText.setVisibility(View.VISIBLE);
timeText.setText(time.getText().toString());
processingText.setText(R.string.processing_commenced);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
广播接收器:
@Override
public void onReceive(Context context, Intent intent) {
// Vibrate the mobile phone
vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
long[] pattern = {0, 10000, 3, 10000};
vibrator.vibrate(pattern, -1); // vibration for 20 seconds
//create as instance of the media player
mediaPlayer = MediaPlayer.create(context, R.raw.alarm_sound);
mediaPlayer.start();
createNotification(context, "AlmaIPC", "IP check is due", "Alert");
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
Intent intent2 = new Intent(context, MainActivity.class);
PendingIntent pi2 = PendingIntent.getActivity(context, 0, intent2, 0);
Long timeEntered =intent.getLongExtra("timeEntered", 0);
AlarmManager.AlarmClockInfo ac=
new AlarmManager.AlarmClockInfo(System.currentTimeMillis() + timeEntered,
pi2);
manager.setAlarmClock(ac, pi);
}
我的 setExact() 参数中的 timecommenced
变量正在正确调试它应该在什么时间触发警报。
在我的广播接收器中,然后我试图传递这个值并添加用户输入的间隔,这将使警报的时间保持完整。例如2.45 然后 3.05.
出于某种原因,我点击 "Processing commenced" 而不是 timecommenced
状态下的警报响起,它立即触发。之后闹钟时间完全关闭,它有自己的想法。
谁能看出我做错了什么或给我一些建议?
谢谢!
"setExact" 在 Android 6+ [API 21+] 上不起作用,顾名思义。当设备未充电且屏幕关闭时,它将大致受到打瞌睡限制。 [注意:从 Android 7 开始问题更加严重,因为它有更激进的 Doze 形式]
要发出可靠的面向用户的警报,应使用 AlarmManager 的 "setAlarmClock" 方法。
AlarmManager am =
(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent1 = new Intent(context, myReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
Intent intent2 = new Intent(context, myActivity.class);
PendingIntent pi2 = PendingIntent.getActivity(context, 0, i2, 0);
AlarmManager.AlarmClockInfo ac=
new AlarmManager.AlarmClockInfo(System.currentTimeMillis() + DELAY,
pi2);
am.setAlarmClock(ac, pi);
来自文档:
设置闹钟
添加到 API 级别 21
void setAlarmClock (AlarmManager.AlarmClockInfo info,
PendingIntent operation)
安排代表闹钟的闹钟,闹钟响起时将用于通知用户。预期是当此警报触发时,应用程序将进一步唤醒设备以告知用户有关警报的信息——打开屏幕、播放声音、振动等。因此,系统通常也会使用这些信息此处提供以告知用户即将到来的警报(如果适用)。
由于这种警报的性质,类似于setExactAndAllowWhileIdle(int, long, PendingIntent),即使系统处于低功耗空闲状态,这些警报也会被允许触发(a.k.a .打瞌睡)模式
要设置超过 1 个闹钟,请在 PendingIntent 中为每个闹钟指定一个唯一的 'requestCode':
static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)
场景: 生产线工人在特定时间间隔进行检查。在我的应用程序中,用户将此时间间隔输入到文本框中。有日期和时间选择器,以便用户可以 select 进程开始的时间。我想在下一次检查到期前 5 分钟发出警报。
例如: 流程从 2.30 开始。用户以 20 分钟为间隔输入。因此,下一次支票将于 2.50 到期。警报应在 2.45 响起。然后将重复此过程,因此下一次检查将是 3.10,警报应在 3.05 响起。
这是我的代码:
MainActivity.calculate();
commencedTime = new Date();
mTime = Calendar.getInstance();
mTime.setTime(alarmTime);
timeCommenced = trimSecsAndMillisecs(mTime).getTimeInMillis();
currentTime = new Date();
currentTime.getTime();
alertDialogBuilder = new AlertDialog.Builder(MainActivity.this);
//set alert
alertDialogBuilder
.setTitle("IP Check frequency: " + time.getText() + " minutes")
.setMessage("Processing commenced at \n" + startTime.getText())
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (currentTime.after(alarmTime)) {
Toast.makeText(MainActivity.this, "Missed first alert", Toast.LENGTH_LONG).show();
}
i = Integer.parseInt(time.getText().toString());
long scTime2 = ((i * 60 * 1000)); //TIME ENTERED IN MILLISECONDS
intent1 = new Intent(MainActivity.this, MyBroadcastReceiver.class);
intent1.putExtra("timeEntered", scTime2);
intent1.putExtra("timeCommenced", timeCommenced);
sendBroadcast(intent1);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
manager.setExact(AlarmManager.RTC_WAKEUP, timeCommenced, pendingIntent);
Toast.makeText(MainActivity.this, "Alert Set", Toast.LENGTH_SHORT).show();
stopped.setVisibility(View.VISIBLE);
commenced1.setVisibility(View.GONE);
//Change editText to TextView
time.setVisibility(View.GONE);
timeText.setVisibility(View.VISIBLE);
timeText.setText(time.getText().toString());
processingText.setText(R.string.processing_commenced);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
广播接收器:
@Override
public void onReceive(Context context, Intent intent) {
// Vibrate the mobile phone
vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
long[] pattern = {0, 10000, 3, 10000};
vibrator.vibrate(pattern, -1); // vibration for 20 seconds
//create as instance of the media player
mediaPlayer = MediaPlayer.create(context, R.raw.alarm_sound);
mediaPlayer.start();
createNotification(context, "AlmaIPC", "IP check is due", "Alert");
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
Intent intent2 = new Intent(context, MainActivity.class);
PendingIntent pi2 = PendingIntent.getActivity(context, 0, intent2, 0);
Long timeEntered =intent.getLongExtra("timeEntered", 0);
AlarmManager.AlarmClockInfo ac=
new AlarmManager.AlarmClockInfo(System.currentTimeMillis() + timeEntered,
pi2);
manager.setAlarmClock(ac, pi);
}
我的 setExact() 参数中的 timecommenced
变量正在正确调试它应该在什么时间触发警报。
在我的广播接收器中,然后我试图传递这个值并添加用户输入的间隔,这将使警报的时间保持完整。例如2.45 然后 3.05.
出于某种原因,我点击 "Processing commenced" 而不是 timecommenced
状态下的警报响起,它立即触发。之后闹钟时间完全关闭,它有自己的想法。
谁能看出我做错了什么或给我一些建议?
谢谢!
"setExact" 在 Android 6+ [API 21+] 上不起作用,顾名思义。当设备未充电且屏幕关闭时,它将大致受到打瞌睡限制。 [注意:从 Android 7 开始问题更加严重,因为它有更激进的 Doze 形式]
要发出可靠的面向用户的警报,应使用 AlarmManager 的 "setAlarmClock" 方法。
AlarmManager am =
(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent1 = new Intent(context, myReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
Intent intent2 = new Intent(context, myActivity.class);
PendingIntent pi2 = PendingIntent.getActivity(context, 0, i2, 0);
AlarmManager.AlarmClockInfo ac=
new AlarmManager.AlarmClockInfo(System.currentTimeMillis() + DELAY,
pi2);
am.setAlarmClock(ac, pi);
来自文档:
设置闹钟 添加到 API 级别 21
void setAlarmClock (AlarmManager.AlarmClockInfo info,
PendingIntent operation)
安排代表闹钟的闹钟,闹钟响起时将用于通知用户。预期是当此警报触发时,应用程序将进一步唤醒设备以告知用户有关警报的信息——打开屏幕、播放声音、振动等。因此,系统通常也会使用这些信息此处提供以告知用户即将到来的警报(如果适用)。
由于这种警报的性质,类似于setExactAndAllowWhileIdle(int, long, PendingIntent),即使系统处于低功耗空闲状态,这些警报也会被允许触发(a.k.a .打瞌睡)模式
要设置超过 1 个闹钟,请在 PendingIntent 中为每个闹钟指定一个唯一的 'requestCode':
static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)