Android设置闹钟立即触发

huangapple go评论83阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2020年9月21日 22:20:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/63994198.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定