每周每天的通知

时间:2020-02-05 22:00:29

标签: android broadcastreceiver

我以前从未安排过通知,需要帮助。 我的应用程序具有包含以下内容的通知实体:

@Parcelize
@Entity
data class Notification(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    var time: Date,
    var daysOfWeek: Set<DayOfWeek>,
    var enabled: Boolean = false
) : Parcelable

我希望此通知在指定的时间触发一周中选定的几天。我也有几种设置通知的方法:

private fun codeForNotification(notification: Notification, dayOfWeek: DayOfWeek) =
        1000 + notification.id * 10 + dayOfWeek.ordinal

    fun checkNotification(notification: Notification, isEnabled: Boolean? = null) = with(notification) {
        if ((isEnabled == null && enabled) || isEnabled == true) daysOfWeek.forEach { dow ->
            setNotification(time, dow, codeForNotification(this, dow))
        } else daysOfWeek.forEach { dow ->
            Intent(appContext, NotificationReceiver::class.java).let { intent ->
                PendingIntent.getBroadcast(
                    appContext,
                    codeForNotification(this, dow),
                    intent,
                    PendingIntent.FLAG_UPDATE_CURRENT
                )
            }.let(alarmManager::cancel)
        }
    }

    fun setNotification(time: Date, dayOfWeek: DayOfWeek, code: Int) {
        c2.time = time
        c1.apply {
            this.time = Date()
            set(Calendar.HOUR_OF_DAY, c2.get(Calendar.HOUR_OF_DAY))
            set(Calendar.MINUTE, c2.get(Calendar.MINUTE))
        }
        c1.set(Calendar.DAY_OF_WEEK, dayOfWeek.calendarValue)
        if (c1.timeInMillis < System.currentTimeMillis()) {
            c1.add(Calendar.DAY_OF_YEAR, 7)
        }
        Intent(appContext, NotificationReceiver::class.java).let {
            PendingIntent.getBroadcast(appContext, code, it, PendingIntent.FLAG_CANCEL_CURRENT)
        }.let {
            alarmManager.setRepeating(
                AlarmManager.RTC_WAKEUP,
                c1.timeInMillis,
                AlarmManager.INTERVAL_DAY * DayOfWeek.values().size,
                it
            )
        }
    }

通知的设置与Coordinates相似(使用检查通知),但是不会触发。

我的接收者班级:

class NotificationReceiver : BroadcastReceiver() {
    companion object {
        const val CHANNEL_ID = "CHANNEL"
        const val NOTIFY_ID = 1111
    }

    override fun onReceive(context: Context?, intent: Intent?) = context?.let{
        val builder: NotificationCompat.Builder = NotificationCompat.Builder(context, CHANNEL_ID)
            .setContentTitle("Notification")
            .setContentText("Hello world")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)

        val notificationManager =
            NotificationManagerCompat.from(context)
        notificationManager.notify(NOTIFY_ID, builder.build())
    } ?: Unit
}

清单有:

<uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".main.notification.NotificationReceiver" />

请帮助我!

2 个答案:

答案 0 :(得分:0)

我认为我有同样的问题。它有助于将清单中的接收器设置为“已导出”。另外,您应该将接收者限制为“通知”操作:

<receiver android:name=".main.notification.NotificationReceiver" android:exported="true">
   <intent-filter>
      <action android:name="android.intent.action.NOTIFY" />
   </intent-filter>
</receiver>

答案 1 :(得分:0)

设置通知渠道已解决此问题:

override fun onReceive(context: Context?, intent: Intent?) = context?.run {
        val notificationManager: NotificationManager? =
            getSystemService(this, NotificationManager::class.java)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            notificationManager?.let(::setNotificationChanel)
            Notification.Builder(context, CHANNEL_ID)
        } else {
            Notification.Builder(context)
        }.setSmallIcon(R.drawable.ic_access_alarm_24px)
            .setContentTitle(getString(R.string.app_name))
            .setContentText(getString(R.string.notification_description))
            .setContentIntent(getActivityIntent(this))
            .setAutoCancel(true)
            .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.ic_access_alarm_24px))
            .build().let { notification ->
                notificationManager?.notify(NOTIFICATION_ID, notification)
            }
    } ?: Unit

    @RequiresApi(Build.VERSION_CODES.O)
    private fun setNotificationChanel(notificationManager: NotificationManager) =
        NotificationChannel(CHANNEL_ID, CHANNEL_ID, NotificationManager.IMPORTANCE_HIGH).apply {
            description = CHANNEL_DESC
            enableLights(true)
            lightColor = Color.RED
            enableVibration(true)
            setShowBadge(true)
        }.let(notificationManager::createNotificationChannel)
相关问题