简体   繁体   中英

problem with alarm manager delay in alarm ringing

I have encountered a problem where when I set a time, there is a delay for the alarm to ring. Sometimes the alarm goes off early too. I am not sure where I did wrong. Hope someone can help me with this problem.

public void showHourPicker(View view) {


    currentHour = calendar.get(Calendar.HOUR_OF_DAY);
    currentMinute = calendar.get(Calendar.MINUTE);

    timePickerDialog = new TimePickerDialog(MainActivity.this, android.R.style.Theme_Holo_Light_Dialog_NoActionBar, new TimePickerDialog.OnTimeSetListener() {
        @Override
        public void onTimeSet(TimePicker timePicker, int hourOfDay, int minutes) {

            if (hourOfDay >= 12) {
                amPm = "PM";
            } else {
                amPm = "AM";
            }
            txtTime.setText(String.format("%02d:%02d ", hourOfDay, minutes) + amPm);

            calendar.set(Calendar.HOUR_OF_DAY,hourOfDay);
            calendar.set(Calendar.MINUTE,minutes);
        }

    }, currentHour, currentMinute, false);

    timePickerDialog.setTitle(" Your Expected Time : " + exp.getText());
    timePickerDialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
    timePickerDialog.show();

    startAlarm(calendar);

}

public void startAlarm(Calendar calendar) {

    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(this, MyBroadcastReceiver.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY,pendingIntent);

}

This is intended behavior as described in AlarmManager.setRepeating :

As of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above.

setRepeating is equal to setInexactRepeating above API 19. If you want to repeat it exactly after a fixed interval then use handler.postDelayed in your Broadcast Receiver. I have attached one of my Broadcast Receiver code with the same implementation

public class AlertReceiver extends BroadcastReceiver {
private MediaPlayer alarmRinger;
@Override
public void onReceive(Context context, Intent alarmIntent) {
   alarmRinger = MediaPlayer.create(context, R.raw.alarmringer);
   runnable.run();
   }
private final Handler handler = new Handler();
private final Runnable runnable = new Runnable() {
    @Override
    public void run() {
        alarmRinger.start();
        handler.postDelayed(this, 3600000);//Change the timing accordingly in MS 
    }
};

}

Here my AlarmManager triggers the Broadcast Receiver and the Broadcast receiver then triggers MediaPlayer to create a mediaPlayer for playing the sound and also triggers runnable.run() which causes Runnable to run. When the runnable is triggered, the mediaPlayer runs and plays the sound and then the handler.postDelayed is set to repeat the task of Runnable again in 1 hour (3600000 ms), this is repeated infinitely or till you kill the runnable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM