I am making a alarm clock program where the user enters a time and at that time a sound will play. However I cannot figure out a simple way of actually playing the sound at the right time. Any thoughts on how to achieve this ? I will provide the source code
Code:
package alarmClock;
import java.util.*;
import java.math.*;
import java.io.*;
import java.time.*;
import java.time.format.*;
import javax.sound.sampled.*;
public class AlarmTImer {
public static void main(String[] args) throws UnsupportedAudioFileException, IOException, LineUnavailableException {
Scanner scanner = new Scanner(System.in);
// audio source
File audioFile = new File("C:\\Users\\zayaa\\Documents\\alarm Clock Beeps Sound Effect.wav");
AudioInputStream audioStream = AudioSystem.getAudioInputStream(audioFile);
Clip clip = AudioSystem.getClip();
// String response = scanner.next();
/* clip.open(audioStream);
clip.start(); */
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm");
String time = LocalTime.now().format(dtf);
// LocalDateTime currentTime = LocalDateTime.parse(time, dtf);
LocalTime currentTime = LocalTime.parse(time, dtf);
System.out.println(time);
String userInp = "";
System.out.println("Enter hour for alarm (24hr): ");
String hour = scanner.nextLine();
System.out.println("Enter mins for alarm: ");
String mins = scanner.nextLine();
userInp = userInp hour ":" mins;
System.out.println("User inputted: " userInp);
LocalTime userTime = LocalTime.parse(userInp, dtf);
System.out.println();
while (!currentTime.equals(userTime)) {
Duration timeRemaining = Duration.between(currentTime, userTime);
long seconds = timeRemaining.getSeconds(); // no get minutes function
long minutes = ((seconds % 3600) / 60); // conversion
System.out.println("Time remaining: " minutes " mins");
if (currentTime.equals(userTime)) {
System.out.println("The time has come.. ");
clip.open(audioStream);
clip.start();
break;
}
}
}
}
CodePudding user response:
LocalDateTime now = LocalDateTime.now();
LocalDateTime alarm =
LocalDateTime.now()
.withHour(Integer.parseInt(hour))
.withMinute(Integer.parseInt(minute))
.withSecond(0);
long secondsInBetween = Duration.between(now, alarm).getSeconds();
try {
// sleep for milliseconds
Thread.sleep(secondsInBetween * 1000);
// play sound
} catch (InterruptedException e) {
System.err.println("Interrupted!");
}
CodePudding user response:
- Note that you are never actually updating
currentTime
, so the condition will always be false. - Also note that the condition in your
while
loop is the same as thebreak
condition. if for some reason the current time were to update before the nestedif
was reached, you would simply leave the loop and end the program without triggering the alarm. - You are using
time.equals()
, so if the time has passed in between checks - it's infinite loop time. Usetime.isBefore()
ortime.isAfter()
. - Lastly - this program is very wasteful as the cpu keeps working and calculating until the alarm time. See Udo's answer for a better solution.