[英]Android/Java - CountDown Timer not working
I am making a timer as part of my app. 我正在将计时器作为应用程序的一部分。 I followed a tutorial, and made some modifications to the program to better suit my needs. 我遵循了教程,并对程序进行了一些修改,以更好地满足我的需求。 However, when I run the app, I get the default value of the timerTextView (defined in xml), or just random numbers. 但是,当我运行应用程序时,我得到了timerTextView的默认值(在xml中定义),或者只是随机数。 What is going wrong? 怎么了?
Update : Here is the coomplete code for the activity: 更新 :这是该活动的完整代码:
public class Main7Activity extends AppCompatActivity {
private TextView countDownText;
private CountDownTimer countDownTimer;
//private long timeLeftInMilliseconds = 1000*60*60*24*7*1;
public TextView textView3;
public TextView textView4;
public TextView textView5;
public TextView textView6;
public long timeLeftInMilliseconds;
//private int daysToGo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main7);
textView3 = (TextView) findViewById(R.id.testText);
textView4 = (TextView) findViewById(R.id.testText2);
textView5 = (TextView) findViewById(R.id.testText3);
textView6 = (TextView) findViewById(R.id.testText4);
//textView3.setText(Integer.toString(Main6Activity.progress2));
Calendar now = Calendar.getInstance();
textView3.setText("LMP date : " + Main6Activity.textView.getText());
int currentDayOfYear = now.get(Calendar.DAY_OF_YEAR);
//Day of year is the LMP date
now.set(Calendar.DAY_OF_YEAR, Main6Activity.progress2);
int lmpDate = now.get(Calendar.DAY_OF_YEAR);
//Day of year is due date
now.add(Calendar.DAY_OF_YEAR, 7*40);
textView4.setText("Due Date: " + now.get(Calendar.DATE) + "-"
+ (now.get(Calendar.MONTH) + 1) + "-" + now.get(Calendar.YEAR));
int dueDate = now.get(Calendar.DAY_OF_YEAR);
if (dueDate < 365 && lmpDate > 82){
dueDate = dueDate + (365);
}
if (lmpDate<82 && lmpDate>49){
dueDate = dueDate + lmpDate;
}
if (lmpDate<50) {
textView5.setText("Congratulations on Delivery");
}
else {
textView5.setText(Integer.toString(dueDate));
}
//textView5.setText(now.getTime().toString());
//int currentDayOfYear = Calendar.DAY_OF_YEAR;
int daysToGo = dueDate - currentDayOfYear;
textView6.setText(Integer.toString(daysToGo));
timeLeftInMilliseconds = 1000*60*60*24*daysToGo;
countDownText = (TextView) findViewById(R.id.weeks);
startTimer();
}
public void startTimer(){
countDownTimer = new CountDownTimer(timeLeftInMilliseconds, 1000) {
@Override
public void onTick(long millisUntilFinished) {
timeLeftInMilliseconds = millisUntilFinished;
updateTimer();
}
@Override
public void onFinish() {
}
}.start();
}
public void updateTimer(){
int weeks = (int) timeLeftInMilliseconds / 604800000;
int days = (int) (timeLeftInMilliseconds % 604800000) / 86400000;
//int hours = (int) (timeLeftInMilliseconds % 86400000) / 3600000;
//int minutes = (int) (timeLeftInMilliseconds % 3600000) / 60000;
int seconds = (int) (timeLeftInMilliseconds % 60000) / 1000;
String timeLeftText;
timeLeftText = "";
if (weeks < 10) timeLeftText += "0";
timeLeftText += weeks;
timeLeftText += ":";
if (days < 10) timeLeftText += "0";
timeLeftText += days;
//timeLeftText += ":";
//if (hours < 10) timeLeftText += "0";
//timeLeftText += hours;
//timeLeftText += ":";
//timeLeftText += minutes;
//timeLeftText += ":";
if (seconds < 10) timeLeftText += "0";
timeLeftText += seconds;
countDownText.setText(timeLeftText);
}
public void editInfo(View v){
Intent intent = new Intent(Main7Activity.this, Main6Activity.class);
startActivity(intent);
}
} }
I also need the timer to run in the background. 我还需要计时器在后台运行。 Will this code do that? 这段代码能做到吗?
Thanks. 谢谢。
Try the code below. 试试下面的代码。
Timer_Service.java Timer_Service.java
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.util.Log;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
public class Timer_Service extends Service {
public static String str_receiver = "your_package_name.receiver";
private Handler mHandler = new Handler();
Calendar calendar;
SimpleDateFormat simpleDateFormat;
String strDate;
Date date_current, date_diff;
SharedPreferences mpref;
SharedPreferences.Editor mEditor;
private Timer mTimer = null;
public static final long NOTIFY_INTERVAL = 1000;
Intent intent;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
mpref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
mEditor = mpref.edit();
calendar = Calendar.getInstance();
simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 5, NOTIFY_INTERVAL);
intent = new Intent(str_receiver);
}
class TimeDisplayTimerTask extends TimerTask {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
calendar = Calendar.getInstance();
simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
strDate = simpleDateFormat.format(calendar.getTime());
Log.e("strDate", strDate);
twoDatesBetweenTime();
}
});
}
}
public String twoDatesBetweenTime() {
try {
date_current = simpleDateFormat.parse(strDate);
} catch (Exception e) {
}
try {
date_diff = simpleDateFormat.parse(mpref.getString("data", ""));
} catch (Exception e) {
}
try {
long diff = date_current.getTime() - date_diff.getTime();
int int_hours = Integer.valueOf(mpref.getString("hours", ""));
long int_timer = TimeUnit.HOURS.toMillis(int_hours);
long long_hours = int_timer - diff;
long diffSeconds2 = long_hours / 1000 % 60;
long diffMinutes2 = long_hours / (60 * 1000) % 60;
long diffHours2 = long_hours / (60 * 60 * 1000) % 24;
if (long_hours > 0) {
String str_testing = diffHours2 + ":" + diffMinutes2 + ":" + diffSeconds2;
Log.e("TIME", str_testing);
fn_update(str_testing);
} else {
mEditor.putBoolean("finish", true).commit();
mTimer.cancel();
}
} catch (Exception e) {
mTimer.cancel();
mTimer.purge();
}
return "";
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e("Service finish", "Finish");
}
private void fn_update(String str_time) {
intent.putExtra("time", str_time);
sendBroadcast(intent);
}
}
Your Timer.java activity: 您的Timer.java活动:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class Timer extends AppCompatActivity implements View.OnClickListener {
private Button btn_start, btn_cancel;
private TextView tv_timer;
String date_time;
Calendar calendar;
SimpleDateFormat simpleDateFormat;
EditText et_hours;
SharedPreferences mpref;
SharedPreferences.Editor mEditor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
init();
}
private void init() {
btn_start = (Button) findViewById(R.id.btn_timer);
tv_timer = (TextView) findViewById(R.id.tv_timer);
et_hours = (EditText) findViewById(R.id.et_hours);
btn_cancel = (Button) findViewById(R.id.btn_cancel);
btn_start.setOnClickListener(this);
btn_cancel.setOnClickListener(this);
mpref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
mEditor = mpref.edit();
try {
String str_value = mpref.getString("data", "");
if (str_value.matches("")) {
et_hours.setEnabled(true);
btn_start.setEnabled(true);
tv_timer.setText("");
} else {
if (mpref.getBoolean("finish", false)) {
et_hours.setEnabled(true);
btn_start.setEnabled(true);
tv_timer.setText("");
} else {
et_hours.setEnabled(false);
btn_start.setEnabled(false);
tv_timer.setText(str_value);
}
}
} catch (Exception e) {
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_timer:
if (et_hours.getText().toString().length() > 0) {
int int_hours = Integer.valueOf(et_hours.getText().toString());
if (int_hours <= 24) {
et_hours.setEnabled(false);
btn_start.setEnabled(false);
calendar = Calendar.getInstance();
simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
date_time = simpleDateFormat.format(calendar.getTime());
mEditor.putString("data", date_time).commit();
mEditor.putString("hours", et_hours.getText().toString()).commit();
Intent intent_service = new Intent(getApplicationContext(), Timer_Service.class);
startService(intent_service);
} else {
Toast.makeText(getApplicationContext(), "Please select the value below 24 hours", Toast.LENGTH_SHORT).show();
}
/*
mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 5, NOTIFY_INTERVAL);*/
} else {
Toast.makeText(getApplicationContext(), "Please select value", Toast.LENGTH_SHORT).show();
}
break;
case R.id.btn_cancel:
Intent intent = new Intent(getApplicationContext(), Timer_Service.class);
stopService(intent);
mEditor.clear().commit();
et_hours.setEnabled(true);
btn_start.setEnabled(true);
tv_timer.setText("");
break;
}
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String str_time = intent.getStringExtra("time");
tv_timer.setText(str_time);
}
};
@Override
protected void onResume() {
super.onResume();
registerReceiver(broadcastReceiver, new IntentFilter(Timer_Service.str_receiver));
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
}
Your activity_timer.xml 您的activity_timer.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/et_hours"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:hint="Hours"
android:inputType="time" />
<Button
android:id="@+id/btn_timer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/btn_cancel"
android:text="Start Timer" />
<Button
android:id="@+id/btn_cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="cancel timer" />
<TextView
android:id="@+id/tv_timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="00:00:00"
android:textColor="#000000"
android:textSize="25dp" />
</RelativeLayout>
Resource reference: this link . 资源参考: 此链接 。
You need to do some modifications according to your requirement. 您需要根据需要进行一些修改。 The countdown will continue even if you close the app. 即使关闭应用程序,倒数计时也会继续。
Try to declare those variables : 尝试声明这些变量:
Handler countHandler ;
Runnable countRunnable ;
private final long INTERVAL = 1000 ; // this the interval period which the timer will be triggered each time
Then change your method like this : 然后像这样更改您的方法:
public void startTimer(){
countHandler = new Handler() ;
countRunnable = new Runnable() {
@Override
public void run() {
updateTimer();
timeLeftInMilliseconds= timeLeftInMilliseconds - INTERVAL ;
if(timeLeftInMilliseconds>=0){
countHandler.postDelayed(this, INTERVAL) ;
} else {
cancelTimer(); // here timer is finished
}
}
} ;
countHandler.post(countRunnable) ;
}
public void cancelTimer(){
countHandler.removeCallbacks(countRunnable);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.