基于Firebase实时数据库的任务管理应用通知创建问题求助
问题描述
我正在使用Firebase Realtime Database开发一款任务管理应用,应用中任务的标题、描述、时间、日期均以字符串形式存储。以下是我用于创建日期时间、保存任务的代码,以及任务数据的Model类,目前在创建通知功能时遇到问题,寻求技术帮助。
新建任务页面(保存任务按钮)
saveButton.setOnClickListener((v) -> { String mTask = tskTitle.getText().toString().trim(); String mDescription = tskDescription.getText().toString().trim(); String id = DBrefrence.push().getKey(); if (currentDate == null) { dateCurrentSelected = DateFormat.getDateInstance().format(new Date()); } else if (currentDate != null) { dateCurrentSelected = currentDate; } if (FINAL_TIME == null) { TimeCurrent = timePickerBTN.getText().toString(); //notificationtime = timePickerBTN.get } else if (FINAL_TIME != null) { TimeCurrent = FINAL_TIME; } String Time = FINAL_TIME; if (TextUtils.isEmpty(mTask)) { tskTitle.setError("Title Required"); return; } if (TextUtils.isEmpty(mDescription)) { tskDescription.setError("Description Required"); return; } else { pdLoader.setTitle("Saving Task"); pdLoader.setMessage("Please wait"); pdLoader.setCanceledOnTouchOutside(false); pdLoader.show(); final int min = 10; final int max = 8000000; final int random = new Random().nextInt((max - min) + 1) + min; String UslID = String.valueOf(random); String EmptyId = ""; Model model = new Model(mTask, mDescription, id, dateCurrentSelected, TimeCurrent,UslID, finalColorCard); DBrefrence.child(id).setValue(model).addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { Intent intent = new Intent(NewTaskActivity.this, MainActivity.class); startActivity(intent); finish(); Toast.makeText(NewTaskActivity.this, "Task has been successfully added", Toast.LENGTH_SHORT).show(); pdLoader.dismiss(); } else { Toast.makeText(NewTaskActivity.this, "Failed To Add Task", Toast.LENGTH_SHORT).show(); pdLoader.dismiss(); } } }); } });
以下是我创建日历和时间选择器的代码
日历选择回调
@Override public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) { calendarUniversal = Calendar.getInstance(); calendarUniversal.set(Calendar.YEAR, year); calendarUniversal.set(Calendar.MONTH, month); calendarUniversal.set(Calendar.DAY_OF_MONTH, dayOfMonth); currentDate = DateFormat.getDateInstance().format(calendarUniversal.getTime()); datePickerBTN.setText(currentDate); }
日历选择器类
public class DatePicker extends DialogFragment { @NonNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { Calendar calendar = Calendar.getInstance(); int year = calendar.get(Calendar.YEAR); int Month = calendar.get(Calendar.MONTH); int day = calendar.get(Calendar.DAY_OF_MONTH); return new DatePickerDialog(getActivity(), (DatePickerDialog.OnDateSetListener) getActivity(), year, Month, day); } }
时间选择器对话框
timePickerBTN.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { TimePickerDialog timePickerDialog = new TimePickerDialog(NewTaskActivity.this, new TimePickerDialog.OnTimeSetListener() { @Override public void onTimeSet(TimePicker timePicker, int hourOfDay, int Minute) { TimeHour = hourOfDay; TimeMinute = Minute; calendarUniversal = Calendar.getInstance(); calendarUniversal.set(0, 0, 0, TimeHour, TimeMinute); timePickerBTN.setText(android.text.format.DateFormat.format("hh:mm aa", calendarUniversal)); FINAL_TIME = timePickerBTN.getText().toString(); } }, 12, 0, false); timePickerDialog.updateTime(TimeHour, TimeMinute); timePickerDialog.show(); } });
任务数据的Model类
public class Model { private String task, description, id, date,time,UselessID, ColorCode; long notificationTime; public Model() {} public Model(String task, String description, String id, String date, String time, String UslID, String Tskcolor /*long notificationTime*/) { this.task = task; this.description = description; this.id = id; this.date = date; this.time = time; this.UselessID = UslID; this.ColorCode = Tskcolor; // this.notificationTime = notificationTime; } public String getTask() { return task; } public void setTask(String task) { this.task = task; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getColorCode() {return ColorCode;} public void setColorCode(String colorCode) {ColorCode = colorCode;} public String getId() { return id; } public void setId(String id) { this.id = id; } public String getUselessID() { return UselessID; } public void setUselessID(String uselessID) { UselessID = uselessID; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getTime() {return time;} public void setTime(String time) {this.time = time;} }
通知功能解决方案
1. 存储时间戳而非纯字符串日期
当前代码中仅存储了日期时间的字符串格式,不利于定时通知计算,需修改为存储时间戳:
- 取消Model类中
notificationTime的注释,完善构造方法与getter/setter:private long notificationTime; public Model(String task, String description, String id, String date, String time, String UslID, String Tskcolor, long notificationTime) { // 保留原有字段赋值 this.notificationTime = notificationTime; } public long getNotificationTime() { return notificationTime; } public void setNotificationTime(long notificationTime) { this.notificationTime = notificationTime; } - 修改时间选择回调,合并日期与时间计算时间戳:
@Override public void onTimeSet(TimePicker timePicker, int hourOfDay, int Minute) { TimeHour = hourOfDay; TimeMinute = Minute; // 复用选择日期时的calendarUniversal实例,避免重新创建 calendarUniversal.set(Calendar.HOUR_OF_DAY, TimeHour); calendarUniversal.set(Calendar.MINUTE, TimeMinute); calendarUniversal.set(Calendar.SECOND, 0); timePickerBTN.setText(android.text.format.DateFormat.format("hh:mm aa", calendarUniversal)); FINAL_TIME = timePickerBTN.getText().toString(); // 计算时间戳 long notificationTimestamp = calendarUniversal.getTimeInMillis(); } - 保存任务时传入时间戳:
Model model = new Model(mTask, mDescription, id, dateCurrentSelected, TimeCurrent,UslID, finalColorCard, notificationTimestamp);
2. 实现定时通知逻辑
使用AlarmManager结合广播接收器触发通知:
- 创建通知广播接收器:
public class NotificationReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String taskTitle = intent.getStringExtra("task_title"); String taskDesc = intent.getStringExtra("task_desc"); NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "TASK_CHANNEL") .setSmallIcon(R.drawable.ic_notification) .setContentTitle(taskTitle) .setContentText(taskDesc) .setPriority(NotificationCompat.PRIORITY_DEFAULT); NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); notificationManager.notify((int) System.currentTimeMillis(), builder.build()); } } - 在AndroidManifest中注册接收器:
<receiver android:name=".NotificationReceiver" /> - 保存任务成功后设置定时任务:
if (task.isSuccessful()) { // 原有跳转、Toast逻辑 Intent notifyIntent = new Intent(NewTaskActivity.this, NotificationReceiver.class); notifyIntent.putExtra("task_title", mTask); notifyIntent.putExtra("task_desc", mDescription); PendingIntent pendingIntent = PendingIntent.getBroadcast( NewTaskActivity.this, Integer.parseInt(UslID), notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE ); AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, notificationTimestamp, pendingIntent); }
3. 创建Android 8.0+通知渠道
在应用启动时初始化通知渠道:
private void createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { CharSequence name = "任务提醒"; String description = "任务截止时间通知"; int importance = NotificationManager.IMPORTANCE_DEFAULT; NotificationChannel channel = new NotificationChannel("TASK_CHANNEL", name, importance); channel.setDescription(description); NotificationManager notificationManager = getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(channel); } }
内容的提问来源于stack exchange,提问作者Divyanshu saraswat
相关产品推荐
相关产品推荐

