#java #android #countdowntimer
#java #Android #countdowntimer
Вопрос:
Я везде искал ответ на эту дилемму. Таймер обратного отсчета (bsCountDownTimer) не запускается, когда это необходимо. Когда я нажимаю кнопку, предполагается, что она запускает OnTick(), правильно? Однако, только после того, как я перейду к другому действию и перейду назад с помощью кнопки ВВЕРХ, или выхожу из приложения или уничтожаю его и перезапускаю, OnTick () начинает обновлять текст и отправлять информацию в LogCat, как это указано.
Я думаю, что эта проблема относится исключительно к подклассу CDT, onBsButtonClick(), onCreate() или, возможно, к onResume() / onPause().
Вот часть исходного кода.
public class HomeActivity extends Activity {
@SuppressLint("NewApi") @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
if(bsTimeStamp!=0){bsIsRunning=true;}
if(bsTimeStamp==0){bsIsRunning=false;}
lastFed=(TextView)findViewById(R.id.lastFedTextView);
feedAt=(TextView)findViewById(R.id.feedAtTextView);
daysText = (EditText)findViewById(R.id.editTextDays);
hoursText = (EditText)findViewById(R.id.editTextHours);
minutesText = (EditText)findViewById(R.id.editTextMinutes);
daysText.setText("");
hoursText.setText("");
minutesText.setText("");
// get timeStamp and boolean from onFeedButtonClick() START
final SharedPreferences prefs = this.getPreferences(Context.MODE_PRIVATE);
feedClickTimeStamp = prefs.getLong("savedOnFeedClick", placeholder);
bsTimeStamp = prefs.getLong("savedOnBsClick", bsProgress);
bsPlaceholder = prefs.getLong("saved placeholder", bsPlaceholder);
bsIsRunning = prefs.getBoolean("bs is running", bsIsRunning);
progressbs = Long.toString(bsProgress);
placeholderbs = Long.toString(bsPlaceholder);
timestampbs = Long.toString(bsTimeStamp);
timestamp = Long.toString(feedClickTimeStamp);
LAST_FED = prefs.getString("lastFed", LAST_FED);
FEED_AT = prefs.getString("feedAt", FEED_AT);
feedAt.setText("Feed at: " FEED_AT);
lastFed.setText("Last fed at: " LAST_FED);
// get timeStamp and boolean from onFeedButtonClick() END
DateTime date = new DateTime();
long currentTime = date.getMillis();
Long bsDiffInMillis;
if(bsIsRunning=false) {
bsDiffInMillis = 0L;
}
else {
bsDiffInMillis = currentTime - bsTimeStamp;
bsPlaceholder -= bsDiffInMillis;
}
Integer bsDiffInt = Integer.valueOf(bsDiffInMillis.intValue());
int roundedDiff = (bsDiffInt 500) / 1000 * 1000;
j = roundedDiff - 2000;
// BS PROGRESS BAR START
bsProgressBar = (ProgressBar)findViewById(R.id.bsProgressBar);
bsProgressBar.setProgress(j);
Long bsPlaceholderLong = bsPlaceholder;
final Integer setMax = Integer.valueOf(bsPlaceholderLong.intValue());
bsProgressBar.setMax(setMax);
setProgressBarVisibility(true);
if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB){
bsProgressBar.setRotation(180);
} else{
// FIND A WAY TO ROTATE PROGRESSBAR BEFORE API 11 (3.0)
}
timeDisplayBs=(TextView)findViewById(R.id.bs_countdown); ((TextView)findViewById(R.id.bs_countdown)).setText(convertMillisForCrafting(bsPlaceholder-ji));
millisInFuture = bsPlaceholder;
bsCountDownTimer = new CDT(millisInFuture, countDownInterval);
// START BS BUTTON LISTENER //
final Button startBsBtn = (Button) findViewById(R.id.bsButton);
startBsBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onBsButtonClick(view);
} //close onClick
}); //close onClickListener
// END BS BUTTON LISTENER //
if (savedInstanceState != null) {} else {}
}// onCreate END
@Override
protected void onPause() {
super.onPause();
bsCountDownTimer.cancel();
}
@SuppressLint("NewApi") @Override
protected void onResume() {
super.onResume();
SharedPreferences prefs = this.getPreferences(Context.MODE_PRIVATE);
bsIsRunning = prefs.getBoolean("bs is running", bsIsRunning);
if(feedClickTimeStamp>0){
mountCountDownTimer.start();
}
if(bsIsRunning==true) {
bsCountDownTimer.start();
bsIsRunning=true;
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("bs is running", bsIsRunning).commit();
}
if(bsIsRunning==false){
bsIsRunning=false;
String progressBarTitleBs = "blacksmithing research";
timeDisplayBs = (TextView)findViewById(R.id.bs_countdown);
timeDisplayBs.setText(progressBarTitleBs.toUpperCase(preferredLocale));
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("bs is running", bsIsRunning).commit();
}
}
public class CDT extends CountDownTimer {
public CDT(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
millisInFuture = prefs.getLong("saved placeholder", bsPlaceholder);
timeDisplayBs=(TextView)findViewById(R.id.bs_countdown);
}
@Override
public void onTick(long millisInFuture) {
Log.v("bsTimer", "Tick of Progress " ji " " millisInFuture);
ji =1;
j =1000;
bsProgressBar.setProgress(j);
timeDisplayBs.setText(convertMillisForCrafting(millisInFuture-ji));
}
@Override
public void onFinish() {
bsCountDownTimer.cancel();
j=0;
ji=0;
bsPlaceholder = 0;
bsTimeStamp = 0;
bsProgressBar.setProgress(0);
String progressBarTitleBs = "blacksmithing research";
timeDisplayBs = (TextView)findViewById(R.id.bs_countdown);
timeDisplayBs.setText(progressBarTitleBs.toUpperCase(preferredLocale));
}
}
public void onBsButtonClick(View view) {
final SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
bsTimeStamp = prefs.getLong("savedOnBsClick", bsProgress);
bsPlaceholder = prefs.getLong("saved placeholder", bsPlaceholder);
bsIsRunning = prefs.getBoolean("bs is running", bsIsRunning);
EditText daysText = (EditText)findViewById(R.id.editTextDays);
EditText hoursText = (EditText)findViewById(R.id.editTextHours);
EditText minutesText = (EditText)findViewById(R.id.editTextMinutes);
int daysPh;
int hoursPh;
int minutesPh;
String daysStr = daysText.getText().toString();
String hoursStr = hoursText.getText().toString();
String minutesStr = minutesText.getText().toString();
if (daysStr.matches("") amp;amp; hoursStr.matches("") amp;amp; minutesStr.matches("")) {
Toast.makeText(this, "You did not enter DAYS, HOURS, or MINUTES.", Toast.LENGTH_LONG).show();
return;
}
if(bsIsRunning==false){
bsPlaceholder = 0;
bsTimeStamp = 0;
bsIsRunning=true;
j=0;
bsProgressBar.setProgress(0);
Long bsPlaceholderLong = bsPlaceholder;
final Integer setMax = Integer.valueOf(bsPlaceholderLong.intValue());
bsProgressBar.setMax(setMax);
if(daysText.getText().toString().equals("")){
daysText.setText("0");
}
if(hoursText.getText().toString().equals("")){
hoursText.setText("0");
}
if(minutesText.getText().toString().equals("")){
minutesText.setText("0");
}
daysPh = Integer.parseInt(daysText.getText().toString());
hoursPh = Integer.parseInt(hoursText.getText().toString());
minutesPh = Integer.parseInt(minutesText.getText().toString());
daysText.setText("");
hoursText.setText("");
minutesText.setText("");
SharedPreferences.Editor editor = prefs.edit();
bsPlaceholder = getMillisForCrafting(daysPh, hoursPh, minutesPh);
millisInFuture = bsPlaceholder; //VITAL
DateTime dt = new DateTime();
bsProgress = dt.getMillis();
editor.putBoolean("bs is running", bsIsRunning).commit();
editor.putLong("savedOnBsClick", bsProgress).commit();
editor.putLong("saved placeholder", bsPlaceholder).commit();
bsCountDownTimer.start();
} //close if bsIsRunning==false
else if(bsIsRunning==true){
view.invalidate();
new AlertDialog.Builder(HomeActivity.this)
.setTitle("New Blacksmithing Research Timer? (erases current)")
.setMessage("Are you sure you want to start a new timer? n(Current timer will be erased.)")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
bsPlaceholder = 0;
bsTimeStamp = 0;
bsCountDownTimer.cancel();
bsIsRunning=true;
j=0;
bsProgressBar.setProgress(0);
String progressBarTitleBs = "blacksmithing research";
timeDisplayBs = (TextView)findViewById(R.id.bs_countdown);
timeDisplayBs.setText(progressBarTitleBs.toUpperCase(preferredLocale));
EditText daysText = (EditText)findViewById(R.id.editTextDays);
EditText hoursText = (EditText)findViewById(R.id.editTextHours);
EditText minutesText = (EditText)findViewById(R.id.editTextMinutes);
if(daysText.getText().toString().equals("")){
daysText.setText("0");
}
if(hoursText.getText().toString().equals("")){
hoursText.setText("0");
}
if(minutesText.getText().toString().equals("")){
minutesText.setText("0");
}
int daysPh = Integer.parseInt(daysText.getText().toString());
int hoursPh = Integer.parseInt(hoursText.getText().toString());
int minutesPh = Integer.parseInt(minutesText.getText().toString());
SharedPreferences.Editor editor = prefs.edit();
bsPlaceholder = getMillisForCrafting(daysPh, hoursPh, minutesPh);
DateTime dt = new DateTime();
bsProgress = dt.getMillis();
editor.putBoolean("bs is running", bsIsRunning).commit();
editor.putLong("savedOnBsClick", bsProgress).commit();
editor.putLong("saved placeholder", bsPlaceholder).commit();
Long bsPlaceholderLong = bsPlaceholder;
final Integer setMax = Integer.valueOf(bsPlaceholderLong.intValue());
bsProgressBar.setMax(setMax);
daysText.setText("");
hoursText.setText("");
minutesText.setText("");
bsCountDownTimer.start();
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
}return;
}
public static Long getMillisForCrafting(int daysPh, int hoursPh, int minutesPh) {
Locale.getDefault();
DateTime bs = new DateTime();
daysPulled = daysPh;
hoursPulled = hoursPh;
minutesPulled = minutesPh;
final long nowInMillis = bs.getMillis();
long days = daysPulled * 86400000;
long hours = hoursPulled * 3600000;
long minutes = minutesPulled * 60000;
long millisToAddToNow = days hours minutes;
long futureDateInMillis = millisToAddToNow nowInMillis;
long millisFromDate = futureDateInMillis - nowInMillis;
return millisFromDate;
}
public void onBsResetButtonClick(View view) {
final SharedPreferences prefs = this.getPreferences(Context.MODE_PRIVATE);
bsTimeStamp = prefs.getLong("savedOnBsClick", bsProgress);
new AlertDialog.Builder(this)
.setTitle("Reset Timer?")
.setMessage("Reset Blacksmithing Research timer? n(Current timer will be erased.)")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
j=0;
bsProgressBar.setProgress(0);
bsCountDownTimer.cancel();
bsIsRunning=false;
String progressBarTitleBs = "blacksmithing research";
timeDisplayBs = (TextView)findViewById(R.id.bs_countdown);
timeDisplayBs.setText(progressBarTitleBs.toUpperCase(preferredLocale));
bsPlaceholder = 0;
bsTimeStamp = 0;
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("bs is running", bsIsRunning).commit();
editor.putLong("savedOnBsClick", 0).commit();
editor.putLong("saved placeholder", 0).commit();
// CLEAR INPUT EDITTEXT AREAS
EditText daysText = (EditText)findViewById(R.id.editTextDays);
EditText hoursText = (EditText)findViewById(R.id.editTextHours);
EditText minutesText = (EditText)findViewById(R.id.editTextMinutes);
daysText.setText("");
hoursText.setText("");
minutesText.setText("");
// CLEAR INPUT EDITTEXT AREAS
}})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
}
@SuppressLint("DefaultLocale")
public static String convertMillis(long milliseconds){
long seconds, minutes, hours;
seconds = milliseconds / 1000;
minutes = seconds / 60;
seconds = seconds % 60;
hours = minutes / 60;
minutes = minutes % 60;
Locale.getDefault();
String time = String.format("d:d:d", hours, minutes, seconds);
return(time);
}
@SuppressLint("DefaultLocale")
public static String convertMillisForCrafting(long milliseconds){
long seconds, minutes, hours, days;
seconds = milliseconds / 1000;
minutes = seconds / 60;
seconds = seconds % 60;
hours = minutes / 60;
days = hours / 24;
hours = hours % 24;
minutes = minutes % 60;
Locale.getDefault();
String timeBs = String.format("d days d hours d minutes d seconds", days, hours, minutes, seconds);
return(timeBs);
}
@Override
protected void onDestroy() {
super.onDestroy(); // Always call the superclass
mProgressBar.destroyDrawingCache();
mountCountDownTimer.cancel();
// bsProgressBar.destroyDrawingCache();
// bsCountDownTimer.cancel();
// android.os.Debug.stopMethodTracing(); // Stop method tracing that the activity started during onCreate()
}
}
Комментарии:
1. Просмотрев ваш код, я полагаю, что ваша проблема, возможно, больше похожа на простую логическую проблему. Я не решил эту проблему, но я скажу, что, я думаю, вам нужно проверить, правильно ли установлена ваша переменная bsIsRunning (Boolean). Если он установлен неправильно, может возникнуть проблема с вызовом onResume(), что имело бы смысл, почему он запускается при переключении действий и навигации по нему, но когда вы хотите, чтобы это было по-другому, это не работает.
2. Спасибо за ваш вклад, я собираюсь исследовать bsIsRunning во всех случаях. Однако, чтобы улучшить этот вопрос для любых других, которые могут его читать, проблема, описанная в вопросе, предшествует созданию логической переменной bsIsRunning. Другими словами, у меня была эта проблема до того, как я создал эту переменную и разместил ее в нескольких местах.
Ответ №1:
Я понял!
CountDownTimer не запускается, потому что переменная из onBsButtonClick() (bsPlaceholder) неправильно передается в onCreate().
Вот что я сделал:
Объявлена глобальная переменная
static long timeInput;
Создан подкласс, который расширяет CountDownTimer:
public class bsTimer extends CountDownTimer {
public bsTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
@Override
public void onTick(long millisInFuture) {
Log.v("bsTimer", "Tick of Progress " ji " " millisInFuture);
ji =1;
j =1000;
bsProgressBar.setProgress(j);
((TextView)findViewById(R.id.bs_countdown)).setText(convertMillisForCrafting(millisInFuture-ji));
}
@Override
public void onFinish() {
// TODO Auto-generated method stub
}
}
Создан экземпляр таймера обратного отсчета в onCreate();
bsCountDownTimer = new bsTimer(timeInput, 1000);
Затем просто создал новый таймер и запустил его в методе onBsButtonClick()!
bsCountDownTimer = new bsTimer(timeInput, 1000).start();