簡體   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