警报延迟,警报管理器未在正确时间触发

时间:2021-06-10 10:49:19

标签: java android alarmmanager

我找到了很多关于这个问题的答案,但没有一个对我有用。我的闹钟延迟了。我想设置一个重复的闹钟。这是我迄今为止尝试过的代码。

报警代码:

Calendar calendar = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm a");
calendar.set(Calendar.HOUR_OF_DAY, timePicker.getCurrentHour());
calendar.set(Calendar.MINUTE, timePicker.getCurrentMinute());
calendar.set(Calendar.SECOND,0);
MyDatabase myDatabase = 
Room.databaseBuilder(getApplicationContext(),MyDatabase.class,"AlarmDB")
                .allowMainThreadQueries()
                .build();

Alarm alarm = new Alarm(newID,title.getText().toString(),timeis,"on",calendar.getTimeInMillis());
        myDatabase.dao().alarmInsertion(alarm);
        startAlarm(calendar,newID,alarm);
    
    private void startAlarm(Calendar c ,Long id,Alarm alarm) {
            AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            Intent intent = new Intent(this, AlaramReceiver.class);
            Bundle args = new Bundle();
            args.putSerializable("alarm",(Serializable)alarm);
            intent.putExtra("DATA",args);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(this, id.intValue(), intent, 0);
            alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(),AlarmManager.INTERVAL_DAY, pendingIntent);
        }

广播接收器

public class AlaramReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        MyDatabase myDatabase = Room.databaseBuilder(context, MyDatabase.class, "AlarmDB")
                .allowMainThreadQueries()
                .build();
        Bundle args = intent.getBundleExtra("DATA");
        Alarm alarm = (Alarm) args.getSerializable("alarm");
        Toast.makeText(context, alarm.getTitle(), Toast.LENGTH_SHORT).show();
        NotificationHelper notificationHelper = new NotificationHelper(context);
        NotificationCompat.Builder nb = notificationHelper.getChannelNotification(alarm.getTitle());
        notificationHelper.getManager().notify(1, nb.build());
        Uri alarmuri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
        if (alarmuri == null) {
            alarmuri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        }
        Ringtone ringtone = RingtoneManager.getRingtone(context, alarmuri);
        ringtone.play();

    }

}

1 个答案:

答案 0 :(得分:0)

正如您在官方文档中看到的 here,由于 Android Kitkat 19 闹钟行为已经改变,基本上没有直接的方法来安排准确的重复闹钟。

<块引用>

注意:从 API 19 (Build.VERSION_CODES.KITKAT) 警报开始 交付不准确:操作系统将转移警报以最大限度地减少 唤醒和电池使用。有新的 API 来支持应用程序 需要严格的交货保证;见 setWindow(int, long, long, android.app.PendingIntent) 和 setExact(int, long, android.app.PendingIntent)。 targetSdkVersion 为的应用程序 早于 API 19 将继续看到之前的行为 所有警报都在请求时准确发送。

作为一种解决方法,您可以设置一个精确的警报,并在触发此警报时再次安排一个新的精确警报。

为了避免自己处理不同的 Android 版本,您可以使用 AlarmManagerCompat 并使用方法 setExact()

例如

val intent = Intent(context,  AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)

AlarmManagerCompat.setExact(alarmManager, AlarmManager.RTC_WAKEUP, whenToTrigger, pendingIntent)

并在您的广播接收器中再次安排准确的警报。

class AlarmReceiver: BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {

            //here schedule an exact alarm again.

            val intent = Intent(context,  AlarmReceiver::class.java)
            val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
            AlarmManagerCompat.setExact(alarmManager, AlarmManager.RTC_WAKEUP, whenToTrigger, pendingIntent)

        }
    }
<块引用>

注意:只有对准确时间有强烈要求的警报 * 交付(例如在要求的时间响起的闹钟)应该是 * 准确安排。强烈建议应用程序不要使用精确的 * 不必要的警报,因为它们会降低操作系统最大限度地减少电池使用的能力。