Android:比较当前时间与TimePicker输入时间时单数字时间匹配异常
Hey Rajat, I see exactly where the problem is—your substring-based time parsing is failing for single-digit hours or minutes because it relies on fixed character positions, which don't hold when the time has only one digit for hour/minute. Let's break this down and fix it step by step.
The Root Cause
When you use substring to slice the time string (like grabbing the first 2 characters for hour), it works fine for times like 10:10 (since the hour is two digits). But for 1:10, the first two characters are 1:, which isn't a valid hour number. This throws off your conditional logic, sending it into the ELSE branch instead of the intended one for single-digit times.
Solution: Use Dynamic Time Splitting Instead of Fixed Substrings
Instead of relying on fixed character indices, split the time string by the colon (:) to separate hours and minutes. This works reliably for both single-digit and double-digit time values.
Step 1: Split the User-Input Time
First, take the time from your TimePicker and split it into hour and minute components:
String targetTime = yourTimePicker.getText().toString(); String[] timeComponents = targetTime.split(":"); // Parse to integers (handle potential invalid input with try-catch) int targetHour = 0; int targetMinute = 0; try { targetHour = Integer.parseInt(timeComponents[0]); targetMinute = Integer.parseInt(timeComponents[1]); } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) { // Handle invalid time format (e.g., show error to user) e.printStackTrace(); }
Step 2: Get Current Time Values
Retrieve the current hour and minute using a reliable time API (choose based on your Android API level):
// For API level <26, use Calendar Calendar currentTime = Calendar.getInstance(); int currentHour = currentTime.get(Calendar.HOUR_OF_DAY); // Use HOUR for 12-hour format int currentMinute = currentTime.get(Calendar.MINUTE); // For API level >=26, use LocalDateTime (cleaner) // LocalDateTime now = LocalDateTime.now(); // int currentHour = now.getHour(); // int currentMinute = now.getMinute();
Step 3: Compare Times & Trigger Vibration
Now compare the integer values directly—no more string-based branch confusion:
@Override public void onTick(long millisUntilFinished) { // Refresh current time each tick Calendar currentTime = Calendar.getInstance(); int currentHour = currentTime.get(Calendar.HOUR_OF_DAY); int currentMinute = currentTime.get(Calendar.MINUTE); if (currentHour == targetHour && currentMinute == targetMinute) { // Trigger vibration Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); if (vibrator != null && vibrator.hasVibrator()) { vibrator.vibrate(1000); // Vibrate for 1 second—adjust as needed } // Optional: Cancel the timer if you don't want repeated vibrations // yourCountDownTimer.cancel(); } }
Why This Works
By splitting the time string dynamically, you avoid the pitfalls of fixed-position substring calls. Whether the user enters 1:10 or 12:34, split(":") will always give you the correct hour and minute as separate elements, which you can safely convert to integers for comparison.
Bonus: Avoid Invalid Inputs
Adding a try-catch block around the integer parsing ensures your app doesn't crash if the user enters a malformed time (like 10-10 instead of 10:10). You can also add input validation to the TimePicker to enforce the correct HH:mm or H:mm format upfront.
内容的提问来源于stack exchange,提问作者Rajat

