【问题标题】:how to make countdown timer from firebase database for android如何从 Android 的 Firebase 数据库制作倒数计时器
【发布时间】:2021-04-19 12:29:08
【问题描述】:

我想从 firebase 数据库制作倒数计时器。计数器应平等地同步到所有用户 并且用户不应控制或操纵计时器。

我尝试使用开始时间作为网络提供的日期,并在 firebase 数据库中设置最终完成时间。倒数计时器应该计算两个时间的差异。

这是我的代码。

清单

<uses-permission android:name="android.permission.WRITE_SETTINGS"
        tools:ignore="ProtectedPermissions" />

主计数器片段

private CountDownTimer mCountDownTimer;
private TextView mTextViewCountDown;
private String dateEnd="";
private long mTimeLeftInMillis;
    
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    dashboardFragment= inflater.inflate(R.layout.fragment_dashboard, container, false);

    startTimer();

    currentUser= FirebaseAuth.getInstance().getCurrentUser();
    mAuth=FirebaseAuth.getInstance();
    timeRef=FirebaseDatabase.getInstance().getReference();

    InitializeFields();
    mTimeLeftInMillis=dateFormat();

    return dashboardFragment;
}

private long dateFormat() {

    long diff=0;

    SimpleDateFormat formatter=new SimpleDateFormat("dd.MM.yyyy, HH:mm");
    formatter.setLenient(false);

    long endTime=0;
    Date endDate;

    try {
        endDate=formatter.parse(dateEnd);
        endTime=endDate.getTime();
    }catch ( ParseException e){
        e.printStackTrace();
    }

    long startTime = System.currentTimeMillis();

    diff=endTime-startTime;
    return diff;
}

private void startTimer() {

    mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
        @Override
        public void onTick(long millisUntilFinished) {
            mTimeLeftInMillis = millisUntilFinished;
            updateCountDownText();
        }
        @Override
        public void onFinish() {

        }
    }.start();
}

private void updateCountDownText() {

    int days=(int) mTimeLeftInMillis/(24*60*60*1000);
    int hours=(int) mTimeLeftInMillis/(60*60*1000)%24;
    int minutes = (int) mTimeLeftInMillis / (60*1000)%60;
    int seconds = (int) mTimeLeftInMillis / 1000%60;
    String timeLeftFormatted = String. format(Locale. getDefault(), "%02d:%02d:%02d:%02d",days,hours, minutes, seconds);
    mTextViewCountDown. setText(timeLeftFormatted);
}

private void InitializeFields() {

    mTextViewCountDown = dashboardFragment.findViewById(R.id.count_down_timer);
}

@Override
public void onStart() {
    super.onStart();
    final DatabaseReference timeRef=FirebaseDatabase.getInstance().getReference().child("Time").child("endTime");
    String timeSettings = android.provider.Settings.System.getString(
        getActivity().getContentResolver(),
        android.provider.Settings.System.AUTO_TIME);
    if (timeSettings.contentEquals("0")) {
        android.provider.Settings.System.putString(
            getActivity().getContentResolver(),
            android.provider.Settings.System.AUTO_TIME, "1");
    }


    timeRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            dateEnd=(String) snapshot.getValue();
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    });
    updateCountDownText();
    startTimer();
}

计数器得到差异但不计数。每次我重新启动应用程序时,它都会获得新的刷新时间,唯一的问题是不算数。

我不知道如何解决它。请任何人。

【问题讨论】:

    标签: android firebase firebase-realtime-database countdowntimer


    【解决方案1】:

    在我看来,有几个问题。

    onCreateView() 中的startTimer() 无用,因为没有初始化任何变量。

    InitializeFields() 也无用,因为在inflate 操作下方检索图形组件是一种常见做法,并且您不需要相同已创建视图的实例。

    不知道timeRefonCreateView() 中指的是什么,因为它没有被使用,并且您在onStart() 方法中有另一个同名的变量。

    您的updateCountDownText() 修改了一个图形组件。所以,它必须在 UI Thread 上调用。

    然后,在 onStart() 中,您将在检索 dateEnd 变量之前启动计时器,因为侦听器模式是异步的。

    这里是我所说的一些修正

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_dashboard, container, false);
        mTextViewCountDown = dashboardFragment.findViewById(R.id.count_down_timer);
    
        currentUser = FirebaseAuth.getInstance().getCurrentUser();
        mAuth = FirebaseAuth.getInstance();
        timeRef = FirebaseDatabase.getInstance().getReference();
    
        mTimeLeftInMillis = dateFormat();
    
        return v;
    }
    
    private long dateFormat() {
    
        long diff = 0;
    
        SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy, HH:mm");
        formatter.setLenient(false);
    
        long endTime = 0;
        Date endDate;
    
        try {
            endDate = formatter.parse(dateEnd);
            endTime = endDate.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
    
        long startTime = System.currentTimeMillis();
    
        diff = endTime - startTime;
        return diff;
    }
    
    
    private void startTimer() {
    
        mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                mTimeLeftInMillis = millisUntilFinished;
                updateCountDownText();
            }
    
            @Override
            public void onFinish() {
    
            }
        }.start();
    }
    
    private void updateCountDownText() {
    
        getActivity().runOnUiThread(() -> {
            int days = (int) mTimeLeftInMillis / (24 * 60 * 60 * 1000);
            int hours = (int) mTimeLeftInMillis / (60 * 60 * 1000) % 24;
            int minutes = (int) mTimeLeftInMillis / (60 * 1000) % 60;
            int seconds = (int) mTimeLeftInMillis / 1000 % 60;
            String timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d:%02d:%02d", days, hours, minutes, seconds);
            mTextViewCountDown.setText(timeLeftFormatted);
        });
    }
    
    @Override
    public void onStart() {
        super.onStart();
        final DatabaseReference timeRef = FirebaseDatabase.getInstance().getReference().child("Time").child("endTime");
        String timeSettings = android.provider.Settings.System.getString(
                getActivity().getContentResolver(),
                android.provider.Settings.System.AUTO_TIME);
        if (timeSettings.contentEquals("0")) {
            android.provider.Settings.System.putString(
                    getActivity().getContentResolver(),
                    android.provider.Settings.System.AUTO_TIME, "1");
        }
    
        timeRef.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                dateEnd = (String) snapshot.getValue();
                updateCountDownText();
                startTimer();
            }
    
            @Override
            public void onCancelled(@NonNull DatabaseError error) {
    
            }
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-19
      • 2016-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多