我正在使用 Firebase 创建一个习惯跟踪器,它可以选择记住一天中的小时和分钟来显示您创建的习惯的通知,问题是当您创建新习惯时,通知会替换旧的小时和分钟警告。
我不想要多个通知,而是使用单个通知显示消息来检查习惯。
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var notificationHelper: NotificationHelper
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Thread.sleep(2000)
installSplashScreen()
notificationHelper = NotificationHelper(applicationContext)
notificationHelper.createNotificationChannel()//create notification
习惯提醒接收器
class HabitReminderReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val notification = buildNotification(context, intent)
val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
manager.notify(DataBaseConstants.NOTIFICATION.notificationID, notification)
}
private fun buildNotification(context: Context, intent: Intent): Notification {
val message = intent.getStringExtra(DataBaseConstants.NOTIFICATION.messageExtra)
return Notification.Builder(context, DataBaseConstants.NOTIFICATION.channelID)
.setSmallIcon(R.drawable.baseline_add_alert_24)
.setContentText(message)
.build()
}
}
NotificationHelper在MainActivity和scheduleNotification中创建通道
class NotificationHelper(private val context: Context) {
fun createNotificationChannel() {
Log.i("NotificationHelper", "Notification Created ")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
DataBaseConstants.NOTIFICATION.channelID,
DataBaseConstants.NOTIFICATION.channelName,
NotificationManager.IMPORTANCE_DEFAULT
)
val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}
fun scheduleNotification(context: Context, intent: Intent) {
//get hour and minute from reminder of habit
val hour = intent.getIntExtra(DataBaseConstants.NOTIFICATION.HOUR, -1)
val minute = intent.getIntExtra(DataBaseConstants.NOTIFICATION.MINUTE, -1)
Log.i("NotificationHelper", "$hour: $minute")
val pendingIntent = PendingIntent.getBroadcast(
context,
DataBaseConstants.NOTIFICATION.notificationID,//Use the unique notification ID as the requestCode
intent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val calendar = Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, hour)
set(Calendar.MINUTE, minute)
set(Calendar.SECOND, 0)
}
val time = calendar.timeInMillis // timeInMillis with reminder hour and minute
Log.i(DataBaseConstants.TAG.ADD_HABIT_FORM_ACTIVITY, "Time in millis: $time")
alarmManager.setRepeating(
AlarmManager.RTC_WAKEUP, time, AlarmManager.INTERVAL_DAY, pendingIntent
)
}
}
添加新习惯并使用NotificationHelper安排提醒的类addHabitFormActivity
private lateinit var notificationHelper: NotificationHelper
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
notificationHelper = NotificationHelper(context = applicationContext)
buttonCreateHabit.setOnClickListener {
//class habit to pass name, user id, icon, reminder with hour and minute...
habit = Habit(
"",//id empty
editName.text.toString(),
editDesc.text.toString(),
FirebaseAuthManager.getCurrentUser?.uid.toString(),
reminder,
dataEnd,
icon,
rangeOptionEnumClass,
goalType,
durationTimer,
arrayListOf()
)
habit.save()//save into firebase the habit
Toast.makeText(
applicationContext,
getString(R.string.save_success),
Toast.LENGTH_SHORT).show()//Toast saved
if (!editReminderTimepick.text.isEmpty()) {
//add hour and minute from class Reminder and name of the habit
var intent = Intent(applicationContext,HabitReminderReceiver::class.java)
intent.putExtra(DataBaseConstants.NOTIFICATION.HOUR, reminder.hour)
intent.putExtra(DataBaseConstants.NOTIFICATION.MINUTE, reminder.minute)
intent.putExtra(DataBaseConstants.NOTIFICATION.messageExtra, habit.name)
notificationHelper.scheduleNotification(this, intent)
}
finish() // finish addHabitFormActivity
}
class DataBaseConstants private constructor() {
object NOTIFICATION {
const val notificationID = 1
const val channelID = "channel1"
const val channelName = "channelName"
const val titleExtra = "titleExtra"
const val messageExtra = "messageExtra"
const val HOUR = "hour"
const val MINUTE = "minute"
}
}
class Reminder {
var enable: Boolean? = false
var hour: Int? = null
var minute: Int? = null
var days: Weekday = Weekday()
}
清单
<receiver android:name=".utils.HabitReminderReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
我找到了解决这个问题的方法:
在 onReceive 中的 HabitReminderReceiver 中,我创建了一个始终显示 1 个固定通知的变量。
class HabitReminderReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val habitId = intent.getIntExtra(DataBaseConstants.NOTIFICATION.habitId, -1)
val notification = buildNotification(context, intent)
val notificationFixed = 1//fixed notification
val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
manager.notify(notificationFixed, notification)
}
在 NotificationHelper 中,变量 habitId 具有 Firebase 习惯 id 的 hashCode,当重复小时和分钟提醒时,它使用 HabiReminderReceive 中设置的相同通知来显示,并且这不会创建多个通知并更新相同的通知新习惯的通知。
val hour = intent.getIntExtra(DataBaseConstants.NOTIFICATION.HOUR, -1)
val minute = intent.getIntExtra(DataBaseConstants.NOTIFICATION.MINUTE, -1)
val habitId = intent.getIntExtra(DataBaseConstants.NOTIFICATION.habitId, -1)
Log.i("NotificationHelper", "$hour: $minute: $habitId")
val pendingIntent = PendingIntent.getBroadcast(
context,
habitId,//add every habit id with hashcode
intent,//load each , hour, minute to show
PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE
)