2017-11-25 4 views
0

내 앱의 일부로 타이머를 만들고 있습니다. 나는 튜토리얼을 따랐고, 나의 필요에 더 잘 부합하도록 프로그램을 수정했다. 그러나, 내가 응용 프로그램을 실행할 때, 나는 timerTextView (XML에서 정의 된)의 기본값을 얻거나 그냥 임의의 숫자를 얻는다. 무슨 일 이니?Android/Java - 카운트 다운 타이머가 작동하지 않습니다.

업데이트 : 여기 활동에 대한 coomplete 코드 :

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); 

} 

}

나는 또한 백그라운드에서 실행하는 타이머가 필요합니다. 이 코드가 그렇게할까요?

감사합니다.

+0

당신이 완전한 활동 코드를 게시 할 수 있습니까? –

+0

countDownText.setText (timeLeftText)가 주 스레드에서 실행되는지 확인하십시오. Ui 항목을 백그라운드 스레드에서 업데이트하려고하면 UI가 실제로 업데이트되지 않을 것이라고 생각합니다. 나는 당신이 당신의 타이머 클래스를 어디에서 실행하는지 안다. 그래서 이것이 사실인지 확실하지 않다. – Saik

답변

0

아래 코드를 사용해보십시오.

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); 
    } 
} 

귀하의 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); 
    } 
} 

귀하의 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> 

자원 참조 : this link.

요구 사항에 따라 약간의 수정이 필요합니다. 앱을 종료하더라도 카운트 다운이 계속됩니다.

+0

도움을 주셔서 감사합니다,하지만 난 완벽한 타이머 애플 리케이션을 만들기 위해 찾고 아니에요. 이것은 내 응용 프로그램의 활동 부분이며 활동 작성시 자동으로 실행해야합니다. – BLRBoy

+0

@BLRBoy 정확히 달성하고자하는 것은 무엇입니까? 카운트 다운 타이머가 앱이 실행될 때까지 백그라운드에서 실행되거나 앱이 종료 된 경우에도 실행되도록 할 수 있습니다. –

+0

앱이 닫힌 경우에도 타이머가 실행되어야합니다. 그러나 제안한 코드에는 시작 및 중지 버튼이 있습니다. 자동으로 실행하려면 코드가 필요합니다. 원래 게시물/질문의 코드에는 daysToGo라는 변수가 있습니다. 카운트 다운 타이머는 현재 날짜로부터 며칠까지 카운트 다운해야합니다. daysToGo는 매일 1 씩 감소합니다. 그러나 내가 게시 한 코드는 작동하지 않습니다. 코드가 실행 중일 때 무작위 값 또는 카운트 다운 텍스트 뷰의 기본값을 얻습니다. – BLRBoy

0

그 변수를 선언하십시오 :

Handler countHandler ; 
    Runnable countRunnable ; 
    private final long INTERVAL = 1000 ; // this the interval period which the timer will be triggered each time 

그런 다음 당신의 방법은 다음과 같이 변경합니다

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); 
    } 
관련 문제