首页 > 解决方案 > 为什么每次打开我的 Android 应用程序时都会显示我的通知?

问题描述

我设置了这段代码(或者我是这么认为的)以在用户的​​ Android 设备上每 7 天显示一次通知,即使用户重新启动他们的设备也是如此。但我看到的副作用是,每次用户打开应用程序时,它也会弹出该通知。

我该如何设置它,以便即使在重新启动后也能正确设置通知,但直到所需时间才会显示。

我有MainActivity这个:

override fun onCreate(savedInstanceState: Bundle?) {
  val bootRec = BootReceiver()
  bootRec.scheduleNotifications(this)
}

它用这个调用BootReceiver

class BootReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == "android.intent.action.BOOT_COMPLETED") {
            scheduleNotifications(context)
        }
    }

    fun scheduleNotifications(context: Context) {
        val receiver = ComponentName(context, BootReceiver::class.java)

        context.packageManager.setComponentEnabledSetting(
            receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP
        )

        val alarmMgr: AlarmManager?

        alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        val alarmIntent: PendingIntent = Intent(context, AlarmReceiver::class.java).let { intent ->
            PendingIntent.getBroadcast(context, 0, intent, 0)
        }

        // Set the alarm to start at 8:30 a.m.
        val calendar: Calendar = Calendar.getInstance().apply {
            timeInMillis = System.currentTimeMillis()
            set(Calendar.DAY_OF_WEEK, 1)
            set(Calendar.HOUR_OF_DAY, 15)
            set(Calendar.MINUTE, 13)
        }

        // setRepeating() lets you specify a precise custom interval--in this case,
        // 1 week.
        alarmMgr.setRepeating(
            AlarmManager.RTC_WAKEUP,
            calendar.timeInMillis,
            AlarmManager.INTERVAL_DAY * 7,
            alarmIntent
        )
    }
}

依次调用AlarmReceiver

class AlarmReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        val notificationManager = context.getSystemService(AppCompatActivity.NOTIFICATION_SERVICE) as NotificationManager
        val notChanId = "icollecteverything"
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val notificationChannel = NotificationChannel(notChanId, "My Notifications", NotificationManager.IMPORTANCE_MAX)
            notificationChannel.enableLights(true)
            notificationChannel.lightColor = Color.BLUE
            notificationChannel.vibrationPattern = longArrayOf(0, 1000, 500, 1000)
            notificationChannel.enableVibration(true)
            notificationManager.createNotificationChannel(notificationChannel)
        }

        // Create an explicit intent for an Activity in your app
        val intentMain = Intent(context, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        }
        val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intentMain, 0)

        val notification = NotificationCompat.Builder(context, notChanId)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setPriority(NotificationManagerCompat.IMPORTANCE_HIGH)
            .setContentIntent(pendingIntent)
            .setContentTitle("Title")
            .setContentText("Notification Text.")
            .setStyle(
                NotificationCompat.BigTextStyle()
                    .bigText("Notification Text."))
            .build()
        notificationManager.notify(1, notification)
    }

}

里面有这个AndroidManifest

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

<receiver android:name=".helper.AlarmReceiver" android:enabled="true"/>
<receiver android:name=".helper.BootReceiver"
        android:exported="true"
        android:enabled="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

标签: androidkotlinpush-notificationnotifications

解决方案


您是否阅读过文档AlarmManager.setRepeating

如果规定的触发时间是过去的,则将立即触发警报,警报计数取决于触发时间相对于重复间隔过去多长时间。

我怀疑这是你问题的根源。

如果是这样,那么解决方案将确保将triggerAtMillis其设置为将来的某个时间。通过一些额外的/不同的Calendar调用可能是可行的。


推荐阅读