英文:
Android setAlarmClock triggering immediately
问题
MainActivity
:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "alarmclock.MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void setAlarm(View view) {
Context context = getApplicationContext();
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
long nextTrigger = SystemClock.elapsedRealtime() + 10 * 1000;
Log.i(TAG, SystemClock.elapsedRealtime() + ": scheduling next alarm at " + nextTrigger);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
AlarmManager.AlarmClockInfo ac = new AlarmManager.AlarmClockInfo(nextTrigger, null);
alarmManager.setAlarmClock(ac, pendingIntent);
}
}
AlarmReceiver
:
public class AlarmReceiver extends BroadcastReceiver {
private static final String TAG = "alarmclock.AlarmReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, SystemClock.elapsedRealtime() + " in AlarmReceiver onReceive()");
}
}
You mentioned that using setExactAndAllowWhileIdle
works fine, but you want to specifically try out setAlarmClock
.
英文:
I created a simple application to try out setAlarmClock()
. There is only a single button in the MainActivity
, and it calls setAlarm
when clicked.
The code is below.
MainActivity
public class MainActivity extends AppCompatActivity {
private static final String TAG = "alarmclock.MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void setAlarm(View view) {
Context context = getApplicationContext();
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
long nextTrigger = SystemClock.elapsedRealtime()+10*1000;
Log.i(TAG, SystemClock.elapsedRealtime() + ": scheduling next alarm at " + nextTrigger);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
AlarmManager.AlarmClockInfo ac = new AlarmManager.AlarmClockInfo(nextTrigger, null);
alarmManager.setAlarmClock(ac, pendingIntent);
}
}
AlarmReceiver
public class AlarmReceiver extends BroadcastReceiver {
private static final String TAG = "alarmclock.AlarmReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, SystemClock.elapsedRealtime() + " in AlarmReceiver onReceive()");
}
}
I am basically triggering the alarm for 10seconds later, but for some reason it's triggering immediately.
2020-09-21 22:09:56.664 17910-17910/com.example.alarmclock I/alarmclock.MainActivity: 3362358: scheduling next alarm at 3372358
2020-09-21 22:09:56.687 17910-17910/com.example.alarmclock I/alarmclock.AlarmReceiver: 3362382 in AlarmReceiver onReceive()
If I use setExactAndAllowWhileIdle
the same code seems to work fine. But I am specifically wanting to try out setAlarmClock
.
答案1
得分: 4
AlarmClockInfo 需要使用挂钟时间:
> 在自纪元以来的挂钟时间毫秒中触发基础闹钟的时间
但您正在使用 elapsedRealtime()
时间,因此请使用 System.currentTimeMillis
来解决此问题。
英文:
The AlarmClockInfo requires a wall time:
> time at which the underlying alarm is triggered in wall time milliseconds since the epoch
but you are using elapsedRealtime()
time so use System.currentTimeMillis
to fix the issue.
答案2
得分: 2
它在我将SystemClock.elapsedRealtime()
更改为System.currentTimeMillis()
之后起作用。
long nextTrigger = System.currentTimeMillis() + 10 * 1000;
在更详细地阅读了文档之后,我意识到AlarmClockInfo
构造函数的第一个参数接受:
> long:以墙上时间表示的基础警报触发时间
> 自纪元以来的毫秒数
这正是 System.currentTimeMillis()
所提供的。
另一方面,SystemClock.elapsedRealtime()
返回的是
> 系统启动后经过的时间...
这将始终比自纪元以来的墙上时间小得多。因此,警报会立即被安排,因为
> 如果所述触发时间在过去,警报将立即触发。
英文:
It worked after I changed from SystemClock.elapsedRealtime()
to System.currentTimeMillis()
.
long nextTrigger = System.currentTimeMillis()+10*1000
After reading the documentation in greater detail, I realise that the first parameter of the AlarmClockInfo
constructor takes
> long: time at which the underlying alarm is triggered in wall time
> milliseconds since the epoch
which is what System.currentTimeMillis()
gives.
On the other hand, SystemClock.elapsedRealtime()
returns the
> time since the system was booted...
which will always be a much smaller number than wall time since epoch. As a result, the alarm gets scheduled immediately because
> If the stated trigger time is in the past, the alarm will be triggered immediately.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论