繁体   English   中英

重复通知问题

[英]Repeating notifications issue

我正在努力处理通知。

我想在通知中随机显示 select 文本(在来自单独的 object 文件NotificationData的 String 对象数组上使用random()方法,其中我只有一个名为notificationData的不可变变量),它应该每天在特定时间出现一次(但现在,为了测试的目的,我在代码中写了每小时出现一次)。 我正在使用AlarmManager进行调度。 首先,当应用程序当前未运行时(或在设备睡眠模式期间),通知不会在指定时间出现,而是在启动应用程序后出现。 第二件事是启动应用程序后,通知几乎会在几秒钟内一条一条地出现。 我真的不明白为什么会这样。 这对我来说很奇怪。

这是NotificationUtils class,我在其中创建通知并将数组中的一个字符串放入setContentText()方法中:

package com.example.quit.notification

class NotificationUtils(context: Context) {
    private var mContext = context
    private lateinit var notificationBuilder: NotificationCompat.Builder
    val notificationManager = NotificationManagerCompat.from(mContext)
    private val CHANNEL_ID = "Notification_Channel"

    init {
        createNotificationChannel()
        initNotificationBuilder()
    }

    fun launchNotification() {
        with(NotificationManagerCompat.from(mContext)) {
            notificationManager.notify(0, notificationBuilder.build())
        }
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val name = "Rady"
            val description = "Codzienne rady dla zdrowiejących osób uzależnionych"
            val importance = NotificationManager.IMPORTANCE_DEFAULT
            val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
                this.description = description
            }

            val notificationManager: NotificationManager = mContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }

    private fun initNotificationBuilder() {
        val sampleIntent = Intent(mContext, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        }
        val pendingIntent: PendingIntent = PendingIntent.getActivity(mContext, 0, sampleIntent, 0)

        val data = NotificationData.notificationData.random()

        notificationBuilder = NotificationCompat.Builder(mContext, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_support)
            .setContentTitle("Rada na dziś")
            .setContentText(data)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
    }
}

第二个 class,我在其中创建重复警报:

package com.example.quit.notification

@SuppressLint("UnspecifiedImmutableFlag")
class AlarmUtils(context: Context) {
    private var mContext = context
    private var alarmManager: AlarmManager? = null
    private var alarmIntent: PendingIntent

    init {
        alarmManager = mContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        alarmIntent = Intent(mContext, AlarmReceiver::class.java).let { mIntent ->
            PendingIntent.getBroadcast(mContext, 100, mIntent, PendingIntent.FLAG_UPDATE_CURRENT)
        }
    }

    fun initRepeatingAlarm(calendar: Calendar) {
        calendar.apply {
            set(Calendar.HOUR_OF_DAY, 20)
            set(Calendar.MINUTE, 30)
            set(Calendar.SECOND, 0)
        }

        alarmManager?.set(
            AlarmManager.RTC_WAKEUP,
            calendar.timeInMillis,
            alarmIntent
        )
    }
}

这是我的AlarmReceiver ,在这种情况下,我会在一小时后设置下一个警报(:

package com.example.quit.notification

class AlarmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        val notificationUtils = NotificationUtils(context!!)
        notificationUtils.launchNotification()

        val calendar = Calendar.getInstance()
        calendar.add(Calendar.HOUR_OF_DAY, 1)
        val alarmUtils = AlarmUtils(context)
        alarmUtils.initRepeatingAlarm(calendar)
    }
}

AndroidManifest.xml文件中我只添加了一行标签:

<receiver android:name=".notification.AlarmReceiver" />

最后一件事 - 在MainActivity class 中,我将这三行放在setContentView()方法之后:

val calendar = Calendar.getInstance()
val alarmUtils = AlarmUtils(this)
alarmUtils.initRepeatingAlarm(calendar)

我将非常感谢任何帮助和解释。

很明显为什么您的通知会立即出现。 AlarmReceiver你这样做:

    val calendar = Calendar.getInstance()
    calendar.add(Calendar.HOUR_OF_DAY, 1)
    val alarmUtils = AlarmUtils(context)
    alarmUtils.initRepeatingAlarm(calendar)

您想要使用当前时间,加上一小时并在该时间(未来 1 小时)安排闹钟。 但是,看看initRepeatingAlarm()正在做什么:

    calendar.apply {
        set(Calendar.HOUR_OF_DAY, 20)
        set(Calendar.MINUTE, 30)
        set(Calendar.SECOND, 0)
    }

initRepeatingAlarm()中,您将小时、分钟和秒设置为固定值(这是闹钟最初响起的时间)。 您正在覆盖传入的Calendar中设置的时间。在这种情况下,设置闹钟时,时间是过去的时间,因此会立即触发闹钟。


关于为什么当设备处于休眠状态时闹钟不起作用,对AlarmManager.set()的调用不被认为是“准确的”,系统可能会延迟闹钟以确保设备不会不断被唤醒(保护电池)。 请参阅文档中的解释。

如果你想让 go 的闹钟正好在这个时候关闭,你需要使用不同的方法,比如setExact() ,你需要声明一个额外的权限SCHEDULE_EXACT_ALARM (如果你的目标是 API 级别 31 或更高)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM