android - 如何从 Android 的 Firebase 数据库制作倒数计时器
问题描述
我想从 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();
}
计数器得到差异但不计数。每次我重新启动应用程序时,它都会获得新的刷新时间,唯一的问题是不算数。
我不知道如何解决它。请任何人。
解决方案
在我看来,有几个问题。
startTimer()
inonCreateView()
是无用的,因为没有变量被初始化。
InitializeFields()
也无用,因为在操作下方检索图形组件是一种常见做法inflate
,您不需要相同创建视图的实例。
In 不知道timeRef
in 指的是什么,onCreateView()
因为它没有被使用,并且您在方法中有另一个同名的变量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) {
}
});
}
推荐阅读
- html - 将图层与身体背景对齐时遇到问题
- node.js - Node.js 和 Azure Web APP 中的缓冲区/Base64 编码问题
- matlab - 调用 Simulink 模型时的 Matlab 脚本“采样时间段”错误
- python - 在 scikit-learn 中使用 Sentence-Bert 和其他功能
- python - 泊松销售额
- swift - 无法将 OUTLET 从 Storyboard 导入到 ViewController
- python - Odoo:如何使用 python 在某些条件下隐藏创建或编辑按钮?
- botframework - 使用 SDK v4 启动编码机器人的陷阱
- flask - Azure Flask 应用程序 | Azure SQL - 带有 load_dotenv() 的 pyodbc.OperationalError 超时
- blazor - Blazor (MudBlazor) MudNumericField keeps returning 0 when no input value