Android: Как сохранить работающий таймер обратного отсчета и отображать сообщение, когда время истекает, когда я занимаюсь другим делом? - PullRequest
1 голос
/ 18 июня 2020

https://codinginflow.com/tutorials/android/countdowntimer/part-3-run-in-background

Я смотрю это руководство, я хочу изменить некоторые вещи: я хочу отобразить сообщение «Тайм-аут» через 6 секунд с помощью CountDownTimer. Он работает, когда я нахожусь в TimerActivity, но когда я go для другого действия (например, WelcomeActivity), приложение не отображает сообщение. Как добиться сообщения «Тайм-аут» в WelcomeActivity?

enter image description here

enter image description here

TimerActivity

class TimerActivity : AppCompatActivity() {
    companion object {
        var START_TIME_IN_MILLIS : Long = 6000
    }
    private var mTextViewCountDown: TextView? = null
    private var mButtonStartPause: Button? = null
    private var mButtonReset: Button? = null
    private var mCountDownTimer: CountDownTimer? = null
    private var mTimerRunning: Boolean = false
    private var mTimeLeftInMillis : Long =0

private var mEndTime : Long = 0

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_timer)
    mTextViewCountDown = findViewById(R.id.text_view_countdown)
    mButtonStartPause = findViewById(R.id.button_start_pause)
    mButtonReset = findViewById(R.id.button_reset)
    btnWelcomeAct.setOnClickListener {
        val intent = Intent(this@TimerActivity, Welcome::class.java)
        startActivity(intent)

    }

    mButtonStartPause!!.setOnClickListener {
        if (mTimerRunning) {
            pauseTimer()
        } else {
            startTimer()
        }

    }

    mButtonReset!!.setOnClickListener {
        resetTimer()
    }
    updateCountDownText()
}

private fun startTimer() {
    mEndTime = System.currentTimeMillis() + mTimeLeftInMillis

    mCountDownTimer = object : CountDownTimer(mTimeLeftInMillis, 1000) {
        override fun onTick(millisUntilFinished: Long) {
            mTimeLeftInMillis = millisUntilFinished
            updateCountDownText()
        }

        override fun onFinish() {
            mTimerRunning = false
            updateButton()
            Toast.makeText(applicationContext,"Time out", Toast.LENGTH_SHORT).show()
        }
    }.start()
    mTimerRunning = true
    updateButton()
}


private fun pauseTimer() {
    mCountDownTimer!!.cancel()
    mTimerRunning = false
    updateButton()
}

private fun resetTimer() {
    mTimeLeftInMillis = START_TIME_IN_MILLIS
    updateCountDownText()
    updateButton()
}


private fun updateCountDownText() {
    val minutes = mTimeLeftInMillis / 1000 / 60
    val seconds = mTimeLeftInMillis / 1000 % 60
    val timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds)
    mTextViewCountDown!!.text = (timeLeftFormatted)

}

private fun updateButton() {
    if (mTimerRunning) {
        mButtonReset!!.setVisibility(View.INVISIBLE)
        mButtonStartPause!!.setText("Pause")
    } else {
        mButtonStartPause!!.setText("Start")
        if (mTimeLeftInMillis < 1000) {
            mButtonStartPause!!.setVisibility(View.INVISIBLE)
        } else {
            mButtonStartPause!!.setVisibility(View.VISIBLE)
        }
        if (mTimeLeftInMillis < START_TIME_IN_MILLIS) {
            mButtonReset!!.setVisibility(View.VISIBLE)
        } else {
            mButtonReset!!.setVisibility(View.INVISIBLE)
        }
    }
}

override fun onStop() {
    super.onStop()
    val prefs = getSharedPreferences("prefs", Context.MODE_PRIVATE)
    val editor = prefs.edit()
    editor.putLong("millisLeft", mTimeLeftInMillis)
    editor.putBoolean("timerRunning", mTimerRunning)
    editor.putLong("endTime", mEndTime)
    editor.apply()
    if (mCountDownTimer != null) {
        mCountDownTimer!!.cancel()
    }
}

override fun onStart() {
    super.onStart()
    val prefs = getSharedPreferences("prefs", Context.MODE_PRIVATE)
    mTimeLeftInMillis = prefs.getLong("millisLeft", START_TIME_IN_MILLIS)
    mTimerRunning = prefs.getBoolean("timerRunning", false)
    updateCountDownText()
    updateButton()
    if (mTimerRunning) {
        mEndTime = prefs.getLong("endTime", 0)
        mTimeLeftInMillis = (mEndTime - System.currentTimeMillis())
        if (mTimeLeftInMillis < 0) {
            mTimeLeftInMillis = 0
            mTimerRunning = false
            updateCountDownText()
            updateButton()
        } else {
            startTimer()
        }
    }
}

override fun onBackPressed() {
    val intent = Intent(this@TimerActivity, Welcome::class.java)
    startActivity(intent)
}
}

Class WelcomeActivity

Как отобразить сообщение «Time Out» в этой активности, когда CountDownTimer в TimerActivity завершен?

class Welcome : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_welcome)
}

1 Ответ

1 голос
/ 18 июня 2020

Есть так много способов обновить пользовательский интерфейс после переключения другого действия. Я поделюсь некоторым способом, который может помочь вам в обновлении пользовательского интерфейса из другого действия:

1) Шина событий

2) Приемник широковещания

3) Если вы используете Архитектура MVVM, затем вы можете создать настраиваемую модель viewModel, которая работает с живым приложением.

Event Bus

вам необходимо добавить зависимость EventBus

1) compile 'de.greenrobot:eventbus:2.4.0'

2) создать pojo

public class DataSyncEvent {
    private final String syncStatusMessage;
    public DataSyncEvent(String syncStatusMessage) {
        this.syncStatusMessage = syncStatusMessage;
    }
    public String getSyncStatusMessage() {
        return syncStatusMessage;
    }
}

3) вызов с таймера обратного отсчета

EventBus.getDefault().post(new DataSyncEvent("Sync SuccessFully”);

4) Подпишитесь на действие, которое вы хотите получить обновление

@Subscribe
public void onEvent(DataSyncEvent syncStatusMessage)
{
    Toast.makeText(this, syncStatusMessage.getSyncStatusMessage(), Toast.LENGTH_SHORT).show();
}

Примечание: Не забыть зарегистрироваться и отменить регистрацию

@Override
protected void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    EventBus.getDefault().unregister(this);
}

Радиоприемник:

1) звонок с таймера обратного отсчета

MyReceiver receiver = new MyReceiver(new Handler()); // Create the receiver
registerReceiver(receiver, new IntentFilter("some.action")); // Register receiver

sendBroadcast(new Intent("some.action"));

2) В другом мероприятии:

public static class MyReceiver extends BroadcastReceiver {

        private final Handler handler; // Handler used to execute code on the UI thread

        public MyReceiver(Handler handler) {
            this.handler = handler;
        }

        @Override
        public void onReceive(final Context context, Intent intent) {
            // Post the UI updating code to our Handler
            handler.post(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(context, "Toast from broadcast receiver", Toast.LENGTH_SHORT).show();
                }
            });
        }
    }   

Спасибо

...