首页 > 解决方案 > 警报管理器和广播接收器不会长期触发

问题描述

我正在尝试在我的应用程序中构建提醒模块以如下方式工作,当用户在确切时间设置警报时它会触发通知。

但是,它在两种情况下失败:

1-当我将闹钟时间设置为下一个 2 小时及以上时

2-如果我从任务管理器中删除了应用程序(完全关闭)

没有触发通知,但是,当我第一次打开应用程序时,我会立即收到所有丢失的通知。

我正在使用警报管理器将警报设置如下:

            val manager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
            val pendingIntent = PendingIntent.getBroadcast(context, requestCode, myIntent, 0)
            when {
                            Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> {
                                manager.setExactAndAllowWhileIdle(
                                    AlarmManager.RTC_WAKEUP,
                                    timeOnDayCalender.timeInMillis,
                                    pendingIntent
                                )
                            }
                            else -> {
                                manager.setExact(
                                    AlarmManager.RTC_WAKEUP,
                                    timeOnDayCalender.timeInMillis,
                                    pendingIntent
                                )
                            }
                        }

并在广播接收器中接收我的警报管理器,如下所示:

class AlarmBroadcast : BroadcastReceiver() {


    override fun onReceive(context: Context?, intent: Intent?) {

        val newIntent = Intent(context, AlarmService::class.java)
        newIntent.type = intent?.type
        newIntent.action = intent?.action

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context?.startForegroundService(newIntent)
        } else {
            context?.startService(newIntent)
        }

    }

}

我的AlarmService课是:

class AlarmService : Service() {

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {

        // show foreground notification to let user there is action happening in background
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
            showForegroundNotification()
        else
            startForeground(
                1,
                Notification()
            )

        handleAlarmRedirection(intent)
        stopSelf(startId) // to destroy service after work is done & remove the fixed notification.

        return START_STICKY
    }

    private fun showForegroundNotification() {
        val channelId =
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                createNotificationChannel()
            } else {
                // If earlier version channel ID is not used
                // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
                ""
            }

        val notificationBuilder = NotificationCompat.Builder(this, channelId)
        val notification = notificationBuilder.setOngoing(true)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setPriority(NotificationCompat.PRIORITY_MIN)
            .setContentTitle("title")
            .setContentText("body")
            .setCategory(Notification.CATEGORY_SERVICE)
            .build()
        startForeground(101, notification)
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private fun createNotificationChannel(): String {
        val chan = NotificationChannel(
            "my_service",
            "My Background Service",
            NotificationManager.IMPORTANCE_NONE
        )
        chan.lightColor = Color.BLUE
        chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
        val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        service.createNotificationChannel(chan)
        return "my_service"
    }

    private fun handleAlarmRedirection(intent: Intent?) {
        // logic for pushing the notification is here
    }

    override fun onDestroy() {
        super.onDestroy()
        stopForeground(true)
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }

}

我也添加了清单的权限:

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

我希望如果有人知道这个案子。

如果有人有好的教程或最佳实践建议,请告诉我,我的目标是 android 31。

标签: androidservicebroadcastreceiveralarmmanager

解决方案


对于那些还和我一样卡在这个问题上的人来说,那是因为我的手机是小米的电池优化。

一旦允许应用程序在没有电池优化的情况下工作,它就会按预期正常工作。

但是,要求用户这样做是一种糟糕的用户体验,因此,如果我发现我会更新答案,我正在寻找更好的解决方案。


推荐阅读