skip to Main Content

I new to Android programming and I want to build Time Speaking clock that will speak the current time in every hour.

Please help me with my code, I want it to say the current time in every hour, but It say it in every second, here is my code.

…………………….
……………………………………………………………………………………………

/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        tts = new TextToSpeech(this, this);

         time_textView = findViewById(R.id.time_textView);
         hour_textView = findViewById(R.id.hour_textView);
        
        
        final Handler handler = new Handler();
        final Runnable runnable = new Runnable() {
            @Override
            public void run() {
                
                Calendar calendar = Calendar.getInstance();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("h:mm:ss", Locale.getDefault());
                String currentTime = simpleDateFormat.format(calendar.getTime());
                time_textView.setText(currentTime);
                
                Hour = calendar.getTime().getHours();
                Minute = calendar.getTime().getMinutes();
                
                if (Hour == 1 && Minute == 00){
                    tts.speak("The time is 1 O'clock", TextToSpeech.QUEUE_FLUSH,null);
                }
                else if (Hour == 2 && Minute == 00){
                    tts.speak("The time is 2 O'clock", TextToSpeech.QUEUE_FLUSH,null);
                }
                else if (Hour == 3 && Minute == 00){
                    tts.speak("The time is 3 O'clock", TextToSpeech.QUEUE_FLUSH,null);
                }
                else if (Hour == 4 && Minute == 00){
                    tts.speak("The time is 4 O'clock", TextToSpeech.QUEUE_FLUSH,null);
                }
                else if (Hour == 5 && Minute == 00){
                    tts.speak("The time is 5 O'clock", TextToSpeech.QUEUE_FLUSH,null);
                }
                if (Hour == 6 && Minute == 00){
                    tts.speak("The time is 6 O'clock", TextToSpeech.QUEUE_FLUSH,null);
                }
                
                handler.postDelayed(this, 1000);
            }
        };
        handler.post(runnable);
    }
    
    @Override
    public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS) {
            int result = tts.setLanguage(Locale.US);
            if (result == TextToSpeech.LANG_MISSING_DATA
                || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                Log.e("TTS", "Language not supported");
            } else {
            }

        } else {
            Log.e("TTS", "Initialization Failed!");
        }
    }
    
    @Override
    public void onDestroy() {
        // Don't forget to shutdown tts!
        if (tts != null) {
            tts.stop();
            tts.shutdown();
        }
        super.onDestroy();
    }
}

2

Answers


  1. I am afraid you created an infinite loop. You created the Runnable and submitted it to the queue handler.post(runnable);. Then inside the run() method you submit it with 1 second delay on with handler.postDelayed(this, 1000);.

    This is why it’s triggered every second. What time does the time_textView show?

    There are better ways how to run scheduled tasks, check on JobScheduler for example

    Login or Signup to reply.
  2. I’m not sure if this is "the right way" to do it, but for the sake of "code sanity" this would be my approach (posting only the modified code):

    ... 
    
    // we move this here, as there's no need to initialize it every time
    final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("h:mm:ss", Locale.getDefault());
    
    final Handler handler = new Handler();
    final Runnable runnable = new Runnable() {
        @ Override
        public void run() {
    
            Calendar calendar = Calendar.getInstance();
            // we save our "now" as a reference so it does not "drift"/"shift" while the code is running
            Date time = calendar.getTime();
            String currentTime = simpleDateFormat.format(time);
            time_textView.setText(currentTime);
            
            // use lowercase for the first letter of variable names otherwise it gets confusing ... 
            // for ex. my variable "time" of type Date, if it was named "Time" ... 
            //  when I would write "Time.getHours()" to get the hours ... One might think that there's a 
            // Class named "Time" ('cause classes usually start with capital letters) and this class has 
            // some static method "getHours", so who reads the code is forced to check to see that it was a variable
            hour = time.getHours();
            minute = time.getMinutes();
            seconds = time.getSeconds();
            if (minute == 0 && seconds == 0) {
                // as said in some comment before, you should only check the minutes and seconds
                // the message string could be a constant and insert the hour value using String.format()
                // for optimized performance, but my Java skills are too rusty for that right now
                tts.speak("The time is " + hour + " O'clock", TextToSpeech.QUEUE_FLUSH, null);
            }
            handler.postDelayed(this, 1000);
            // actually here instead of delaying for 1 second ... you could calculate the "remaing time", how many seconds are
            // missing until the next XX:00:00, and delay for that much
            // for extra "precision", just in case, ... delay only for something like "remaingTime - 10" (or something) and 
            // if the "remaingTime < 10" delay only for 1 second, this way you can be more sure you'll not be missing the 
            // XX:00:00 ... but do this only if you notice "imprecisions" while using postDelayed with long intervals
            // and you care about them
    
        }
    };
    handler.post(runnable);
    ... 
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search