简体   繁体   中英

Time picker performs scheduled task every minute until set time is reached instead of performing it only at set time

I am using a Time Picker on which the user will set a time and then a toast message will be displayed at that time. The problem is that the toast is being displayed every minute until it reaches the set time.

Here are the codes:

public class ManualControlsFragment extends Fragment {

 private TimePicker tp;
    private Calendar calendar;
    long pickedTimeInMillis;
    long timeDifference;

//some Fragment methods

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

       View view = inflater.inflate(R.layout.fragment_manual_controls, container, false);

       tp = (TimePicker) view.findViewById(R.id.lightTimePickerStart);
       tp.setIs24HourView(true);
       calendar = Calendar.getInstance();

       tp.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
            @Override
            public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {

                calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
                calendar.set(Calendar.MINUTE, minute);
                calendar.set(Calendar.SECOND, 0);
                pickedTimeInMillis= calendar.getTimeInMillis();
                // at this point get the current time
                Calendar cal = Calendar.getInstance();
                // now calculate the difference as the user actually selected a time
                timeDifference = pickedTimeInMillis - cal.getTimeInMillis();

                new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        //Do something here
                        Toast.makeText(getActivity().getApplicationContext(), "Bulb is now on", Toast.LENGTH_LONG).show();
                    }
                }, timeDifference);
            }
        });

return view;
    }

I think it's because the onTimeChangedListener in time picker registers each minute while I scroll down the picker to select a minute. Like suppose I have to set the time to 14:30 and currently it is 14:25 on the time picker, I have to scroll down the picker from 25, 26, 27, 28, 29 and then finally to 30 to set it to 14:30. I think this is why the time picker displays the toast at every minute. How can I fix this? And also, I am using Looper.getMainLooper()) in the Handler because I have 4 other threads running in the background in some other fragment.

Try something like this, mHandler.removeMessages(0); will stop the hundler if it's already running, and the last one won't be stoped :

 public class ManualControlsFragment extends Fragment {
    private TimePicker tp;
    private Calendar calendar;
    long pickedTimeInMillis;
    long timeDifference;
//some Fragment methods
    Handler mHandler = new Handler(Looper.getMainLooper());

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_manual_controls, container, false);
        tp = (TimePicker) view.findViewById(R.id.lightTimePickerStart);
        tp.setIs24HourView(true);
        calendar = Calendar.getInstance();
        tp.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
            @Override
            public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
                calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
                calendar.set(Calendar.MINUTE, minute);
                calendar.set(Calendar.SECOND, 0);
                pickedTimeInMillis = calendar.getTimeInMillis();
                // at this point get the current time
                Calendar cal = Calendar.getInstance();
                // now calculate the difference as the user actually selected a time
                timeDifference = pickedTimeInMillis - cal.getTimeInMillis();
                mHandler.removeMessages(0);
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        //Do something here
                        Toast.makeText(getActivity().getApplicationContext(), "Bulb is now on", Toast.LENGTH_LONG).show();
                    }
                }, timeDifference);
            }
        });
        return view;
    }
}

Per the TimePicker documentation, the listener does the following:

Set the callback that indicates the time has been adjusted by the user.

So I think your conclusion is correct by saying when the user scrolls through the timepicker it is repeatedly calling the callback defined in the listener.

Try getting the user defined time from TimePicker.getHour() and TimePicker.getMinute() and compare it to the current system time's minute and hour value every 30 seconds in a new thread. That should accomplish what you need.

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