Получите системное время и добавьте к нему 30 минут, после чего сравните его с другим системным временем.
На самом деле я хочу отключить кнопку на 30 минут.
Приведенный ниже код работает хорошо, но если мы закроем приложение и откроем его в течение 30 минут, кнопка будет активирована.
public static void timmer(final ImageButton btn){
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
isTimerRunning = false;
btn.setEnabled(true);
}
}, 1800000);
}
Теперь я получаю системное время при нажатии кнопки, а затем добавляю к нему 30 минут и сохраняю его в DataManager
(один класс для объекта пользователя). Снова по нажатию кнопки я сравниваю время сохранения с текущим системным временем.
@OnClick(R.id.generalReportBtn)
public void setGeneralReport(ImageButton button) {
Log.e("Data Manager Time: ",DataManager.getInstance().getCurrentUser().getLastTime().MINUTE+"");
Log.e("Current Time: ", java.util.Calendar.getInstance().MINUTE+"");
if(DataManager.getInstance().getCurrentUser().getLastTime().after(java.util.Calendar.getInstance())){
DataManager.getInstance().getCurrentUser().lastTime.set(java.util.Calendar.getInstance().YEAR,java.util.Calendar.getInstance().MONTH,java.util.Calendar.getInstance().DATE,java.util.Calendar.getInstance().HOUR_OF_DAY,java.util.Calendar.getInstance().MINUTE,java.util.Calendar.getInstance().SECOND);
DataManager.getInstance().getCurrentUser().lastTime.add(DataManager.getInstance().getCurrentUser().lastTime.MINUTE,30);
}else if(Utilities.isFirstTimePressed){
Utilities.isFirstTimePressed = false;
DataManager.getInstance().getCurrentUser().lastTime.set(java.util.Calendar.getInstance().YEAR,java.util.Calendar.getInstance().MONTH,java.util.Calendar.getInstance().DATE,java.util.Calendar.getInstance().HOUR_OF_DAY,java.util.Calendar.getInstance().MINUTE,java.util.Calendar.getInstance().SECOND);
DataManager.getInstance().getCurrentUser().lastTime.add(DataManager.getInstance().getCurrentUser().lastTime.MINUTE,30);
}else {
Toast.makeText(mainclass,"Button is disabled for 30 minutes",Toast.LENGTH_SHORT).show();
}
}
Но этот код также не работал для меня.
3 ответа
Calendar.getInstance().YEAR
константа, которая представляет поле года (которое имеет значение, равное 1
). На самом деле, это то же самое, что звонить Calendar.YEAR
непосредственно.
Но это не годовая стоимость Calendar
объект. Когда вы делаете set(java.util.Calendar.getInstance().YEAR
вы устанавливаете год 1
(что, вероятно, не то, что вы хотите). То же самое относится и к MONTH
, MINUTE
и все остальные константы, которые вы используете.
Другая деталь заключается в том, что вам не нужно создавать другой календарь (позвонив по Calendar.getInstance()
) все время. Это избыточно и не обязательно в вашем коде.
Во всяком случае, обо всем по порядку. В первых двух строках вы печатаете MINUTE
константа, а не минутное значение дат. Если вы хотите напечатать полную дату (что гораздо полезнее, чем минуты, IMO), просто позвоните getTime()
метод. Кроме того, установите значения для переменных перед их использованием, это делает код намного чище:
import java.util.Calendar;
Calendar lastTime = DataManager.getInstance().getCurrentUser().getLastTime();
Calendar now = Calendar.getInstance(); // current date/time
Log.e("Data Manager Time: ", lastTime.getTime() + "");
Log.e("Current Time: ", now.getTime() + "");
Напоминаю, что это напечатает даты в часовом поясе JVM устройства по умолчанию. Если вы хотите изменить формат, просто перейдите по этой ссылке.
Если вы все еще хотите распечатать только минуты, измените вызов на getTime()
в get(Calendar.MINUTE)
,
Теперь остальная часть вашей логики (если я правильно понял) будет выглядеть так:
if (lastTime.after(now)) {
lastTime = (Calendar) now.clone(); // lastTime becomes a copy of "now"
lastTime.add(Calendar.MINUTE, 30); // add 30 minutes
} else if (Utilities.isFirstTimePressed) {
Utilities.isFirstTimePressed = false;
lastTime.add(Calendar.MINUTE, 30); // add 30 minutes
} else {
Toast.makeText(mainclass, "Button is disabled for 30 minutes", Toast.LENGTH_SHORT).show();
}
Java новый API даты / времени
Старые занятия (Date
, Calendar
а также SimpleDateFormat
) есть много проблем и проблем дизайна, и они заменяются новыми API.
В Android вы можете использовать ThreeTen Backport, отличный бэкпорт для новых классов даты / времени в Java 8. Чтобы он работал, вам также понадобится ThreeTenABP (подробнее о том, как его использовать здесь).
Один из способов проверить, прошло ли 30 минут, это использовать org.threeten.bp.Instant
учебный класс. Затем вы используете isAfter
метод для сравнения, и org.threeten.bp.temporal.ChronoUnit
добавить 30 минут.
Я также использую org.threeten.bp.ZoneId
преобразовать дату в часовой пояс JVM по умолчанию (просто распечатать). В этой ссылке также есть ответы, которые охватывают новый API, используя DateTimeFormatter
, так что вы можете обратиться к ним, если вы хотите изменить формат.
Я также использую org.threeten.bp.DateTimeUtils
класс для преобразования из и в java.util.Calendar
, Код будет таким:
// convert java.util.Calendar to org.threeten.bp.Instant
Instant lastTime = DateTimeUtils.toInstant(DataManager.getInstance().getCurrentUser().getLastTime());
Instant now = Instant.now();
Log.e("Data Manager Time: ", lastTime.atZone(ZoneId.systemDefault()) + "");
Log.e("Current Time: ", now.atZone(ZoneId.systemDefault()) + "");
if (lastTime.isAfter(now)) {
// add 30 minutes to current date/time
lastTime = now.plus(30, ChronoUnit.MINUTES);
} else if (Utilities.isFirstTimePressed) {
Utilities.isFirstTimePressed = false;
lastTime = lastTime.plus(30, ChronoUnit.MINUTES);
} else {
Toast.makeText(mainclass, "Button is disabled for 30 minutes", Toast.LENGTH_SHORT).show();
}
// convert back to java.util.Calendar (set it anywhere you need)
DateTimeUtils.toGregorianCalendar(lastTime.atZone(ZoneId.systemDefault()));
я использую ZoneId.systemDefault()
, который принимает часовой пояс по умолчанию JVM (тот же, который используется при создании Calendar.getInstance()
так что обычно это не будет большой проблемой, если только пользователь не изменит ее).
Проблема в том, что часовой пояс по умолчанию можно изменить даже во время выполнения, поэтому в идеале можно указать его, если это возможно. API использует имена часовых поясов IANA (всегда в формате Region/City
, лайк America/Sao_Paulo
или же Europe/Berlin
). Избегайте использования трехбуквенных сокращений (например, CST
или же PST
) потому что они неоднозначны и не стандартны.
Вы можете получить список доступных часовых поясов (и выбрать тот, который лучше всего подходит вашей системе), позвонив ZoneId.getAvailableZoneIds()
,
Начните с установки переменных. Тогда ваш код будет легче читать:
java.util.Calendar cal = java.util.Calendar.getInstance();
User user = DataManager.getInstance().getCurrentUser();
Затем используйте эти переменные вместо того, чтобы вызывать Calendar.getInstance() так много раз.
Вы путаете константы и значения. ГОД - это константа, которую вы используете, когда хотите получить значение года.
Вместо этого (которое всегда будет возвращать одно и то же значение, поскольку оно является константой):
java.util.Calendar.getInstance().YEAR
Использовать этот:
cal.get(Calendar.YEAR)
Делайте это в течение всех ваших ГОДОВ, МЕСЯЦЕВ и т. Д., И все будет работать.
Простой способ получить системную метку времени:
long systemTime = System.currentTimeMillis()
Добавьте 30 минут к этому.
systemTime += 180000 //(180000 miliseconds is equivalent to 30 minutes)
Сохраните его в общих настройках. Теперь получите значение из общих настроек и сравните с текущим временем.