提问者:小点点

Android setAlarmClock立即触发


我创建了一个简单的应用程序来试用SetalarmClock()MainActivity中只有一个按钮,单击时它调用SetAlarm

代码在下面。

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()");
    }
}

我基本上会在10秒后触发警报,但由于某种原因,它会立即触发。

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()

如果我使用SetExactAndAllowWhileIdle,相同的代码似乎可以正常工作。但我特别想试用SetalarmClock


共2个答案

匿名用户

AlarmClockInfo需要一个墙时间:

触发基础警报的时间(以墙时间毫秒计)

但是您使用的是ElapsedRealTime()time,因此请使用System.currentTimeMillis修复此问题。

匿名用户

在我从SystemClock.ElapsedRealTime()更改为System.currentTimeMillis()之后,它就起作用了。

long nextTrigger = System.currentTimeMillis()+10*1000

在详细阅读了文档之后,我意识到AlarmClockInfo构造函数的第一个参数接受

长:触发底层警报的时间,以墙时间毫秒为单位

这是System.currentTimeMillis()提供的。

另一方面,SystemClock.ElapsedRealTime()返回

系统启动后的时间。。。

这将永远是一个比划时代以来的墙时间小得多的数字。因此,警报会立即被排定,因为

如果规定的触发时间在过去,则立即触发报警。