Обновлять время и прибавлять часы и минуты

116
07 декабря 2020, 18:10

Нужно, чтобы программа считывала текущее время пользователя, обновляла его каждую минуту. Также, чтобы выводились время и минуты с формате: HH + n часов : mm + t минут

вот как я доставала текущее время:

DateFormat dfh = new SimpleDateFormat("HH:mm");
final String date = dfh.format(Calendar.getInstance().getTime());

Пробовала и другие способы, но приложение либо вылетало, либо показывало какую-то белиберду. как я пыталась обновить время:

    Timer timer = new Timer();
    timer.schedule(new getTimeEverySecond(), 0, 1000); // ставим на выполнение каждую секунду

static class getTimeEverySecond extends TimerTask {
    public void run() {
        DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
        Date date = new Date();
        s = dateFormat.format(date); // каждую секунду обновляем переменную
    }
}

при попытке сделать так, как выше, приложение писало много текста.

Также, через while(true), но все горело красным от такого.

как я пыталась прибавлять время:

 Calendar cal = Calendar.getInstance(); // creates calendar
 cal.setTime(new Date()); // sets calendar time/date
 cal.add(Calendar.HOUR_OF_DAY, 1); // adds one hour
 cal.getTime();

спрашивала вчера похожий вопрос, мне посоветовали доставать время так:

DateTime.now().toLocalDate().toString(DateTimeFormat.forPattern("HH:mm"))
DateTime.now().plusHours(1).plusMinutes(10).toString(DateTimeFormat.forPattern("EEEE dd MMMM, YYYY"))

но, когда я пыталась так сделать, DateTime и DateTimeFormat не распознавались и андроид предлагал сделать новый класс/переменную/метод с такими именами.

Как сделать так, чтобы приложение постоянно обновляло текущее время? Как сделать так, чтобы можно было вывести время в формате HH + n часов : mm + t минут?

Весь мой код фрагмента, в котором пытаюсь это реализовать это:

package com.example.itss;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.app.Fragment;
import android.text.Layout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;
public class PhaseFragment extends Fragment {
    Button timeToWakeUp0;
    Button timeToWakeUp1;
    Button timeToWakeUp2;
    Button timeToWakeUp3;
    Button timeToWakeUp4;
    Button timeToWakeUp5;
    Button timeToWakeUp6;
    Button timeToWakeUp7;
    Button timeToSleep0;
    Button timeToSleep1;
    Button timeToSleep2;
    Button timeToSleep3;
    Button timeToSleep4;
    Button timeToSleep5;
    Button timeToSleep6;
    Button timeToSleep7;
    @RequiresApi(api = Build.VERSION_CODES.O)
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.phase_fragment,container, false);

        DateFormat dfh = new SimpleDateFormat("HH:mm");
        final String date = dfh.format(Calendar.getInstance().getTime());
        Calendar cal = Calendar.getInstance(); // creates calendar
        cal.setTime(new Date()); // sets calendar time/date
        cal.add(Calendar.HOUR_OF_DAY, 1); // adds one hour
        cal.getTime();
        DateTime.now().toLocalDate().toString(DateTimeFormat.forPattern("HH:mm"));
        Timer timer = new Timer();
        timer.schedule(new getTimeEverySecond(), 0, 1000);


        timeToWakeUp0 = v.findViewById(R.id.sleeptime0);
        timeToWakeUp0.setText(DateTime.now().plusHours(1).plusMinutes(10).toString(DateTimeFormat.forPattern("HH:mm")));
        timeToWakeUp1 = v.findViewById(R.id.sleeptime1);
        timeToWakeUp1.setText(timer + "");
        timeToWakeUp2 = v.findViewById(R.id.sleeptime2);
        timeToWakeUp2.setText(date);
        timeToWakeUp3 = v.findViewById(R.id.sleeptime3);
        timeToWakeUp4 = v.findViewById(R.id.sleeptime4);
        timeToWakeUp5 = v.findViewById(R.id.sleeptime5);
        timeToWakeUp6 = v.findViewById(R.id.sleeptime6);
        timeToWakeUp7 = v.findViewById(R.id.sleeptime7);
        timeToSleep0 = v.findViewById(R.id.wakeuptime0);
        timeToSleep1 = v.findViewById(R.id.wakeuptime1);
        timeToSleep2 = v.findViewById(R.id.wakeuptime2);
        timeToSleep3 = v.findViewById(R.id.wakeuptime3);
        timeToSleep4 = v.findViewById(R.id.wakeuptime4);
        timeToSleep5 = v.findViewById(R.id.wakeuptime5);
        timeToSleep6 = v.findViewById(R.id.wakeuptime6);
        timeToSleep7 = v.findViewById(R.id.wakeuptime7);

        timeToWakeUp0.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
        timeToWakeUp1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
        timeToWakeUp2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
        timeToWakeUp3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
        timeToWakeUp4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
        timeToWakeUp5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
        timeToWakeUp6.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
        timeToWakeUp7.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
        timeToSleep0.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
        timeToSleep1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
        timeToSleep2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
        timeToSleep3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
        timeToSleep4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
        timeToSleep5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
        timeToSleep6.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
        timeToSleep7.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });

        return v;
    }
    static class getTimeEverySecond extends TimerTask {
        public void run() {
            DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
            Date date = new Date();
            String s = dateFormat.format(date); // каждую секунду обновляем переменную
        }
    }
}
Answer 1

Решение задачи с использованием класса Timer не очень правильное хотя бы потому, что он не будет срабатывать точно с началом каждой минуты, а у вас, как я понял какой то будильник.

Предлагаю использовать системное широковещательное оповещение, которое рассылается в начале каждой минуты. В своем приложении мы подписываемся на него и при наступлении события обновляем время в виджетах.

Так же код обновления кнопок вызывается каждую минуту и хорошим тоном будет сократить количество создаваемых при этом объектов. В частности для получения времени и вычисления смещения используются статические системные классы (как System.currentTimeMillis() и TimeUnit), которые не создают объектов, вместо использования классов Date, Calendar или JodaTime - расчеты не такие сложные, чтобы использовать здесь их.

Весь код выглядит так (для простоты в примере только три кнопки):

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import java.text.SimpleDateFormat;
import java.util.concurrent.TimeUnit;

public class SomeFragment extends Fragment {
    Button timer1, timer2, timer3;
    BroadcastReceiver broadcastReceiver;
    int timeShifts [][] = {
            {0, 0}, //  смещение времени - 0 часов
            {1, 30}, // смещение времени 1 час 30 мин
            {3, 0} // смещение времени 3 часа
    };
    final int HOUR = 0;
    final int MINUTE = 1;
    SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_main, container, false);
        timer1 = v.findViewById(R.id.timer1);
        timer2 = v.findViewById(R.id.timer2);
        timer3 = v.findViewById(R.id.timer3);
        // устанавливаем время на кнопках
        setTime();
        return v;
    }
    @Override
    public void onStart() {
        super.onStart();
        broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context ctx, Intent intent) {
                // обновляем время каждую минуту
                    setTime();
            }
        };
        // подписываемся на системное событие изменения времени (срабатывает раз в минуту)
        getActivity().registerReceiver(broadcastReceiver, new IntentFilter(Intent.ACTION_TIME_TICK));
    }
    @Override
    public void onStop() {
        super.onStop();
        // отписываемся от события
        if (broadcastReceiver != null)getActivity().unregisterReceiver(broadcastReceiver);
    }

    // метод устанавливает время на кнопках
    private void setTime() {
        long curentTime = System.currentTimeMillis();
        timer1.setText(timeFormat.format(curentTime+ timeToMillis(timeShifts[0][HOUR],timeShifts[0][MINUTE]))); // текущее время
        timer2.setText(timeFormat.format(curentTime + timeToMillis(timeShifts[1][HOUR],timeShifts[1][MINUTE]))); // текущее время + 1 ч 30 мин
        timer3.setText(timeFormat.format(curentTime + timeToMillis(timeShifts[2][HOUR],timeShifts[2][MINUTE]))); // текущее время + 3 ч.
    }
    // метод переводит часы и минуты в милисекунды
    private long timeToMillis(int hour, int minute){
        return TimeUnit.HOURS.toMillis(hour) + TimeUnit.MINUTES.toMillis(minute);
    }
}

вы можете менять смещение времени в процессе работы программы следующим образом (изменяем смещение времени на второй кнопке на 2 часа 15 минут):

timeShifts[1][HOUR] = 2;
timeShifts[1][MINUTE] = 15;
setTime();

ps: отсчет кнопок начинается с 0

Данный код только выводит текст на кнопки и обновляет его каждую минуту, никаких функций реального будильника он не выполняет. Так же никакого действия не будет происходить, если программа не запущена или находится в фоне (то есть условный будильник при этом не сработает). Если вам нужно, чтобы и при закрытом приложении или в фоне тоже шел отсчет времени, то для этого есть класс AlarmManager (пример испльзования). Вы можете использовать код выше для интерфейса приложения, а реальный будильник устанавливать уже через AlarmManager

READ ALSO
В каком формате объект записываются в файл?

В каком формате объект записываются в файл?

Вот информация записанная в файл Как понять этот формат?

148
Вопросы от начинающего [закрыт]

Вопросы от начинающего [закрыт]

Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском

123
Java stream как задать условие?

Java stream как задать условие?

Есть лист Integer, я хочу сделать из него строку с помощью stream, но с условием, что если число больше 10 то добавлять к строке "> 10, ", а если меньше,...

199
NPE при добавлении кнопок на панель калькулятора

NPE при добавлении кнопок на панель калькулятора

Вы создаете панель после строк, в которых добавляете в нее кнопки

157