首页 > 解决方案 > 刷掉应用程序时通知不起作用

问题描述

我正在编写一个简单的应用程序,它最多设置 8 个随机重复警报,发送通知,然后在用户点击通知时生成报价。当应用程序运行时,这一切似乎都可以正常工作,但是当应用程序从最近的应用程序中滑出或强制关闭时,通知不起作用。

我从过去几天开始研究我的研究,但找不到当前的解决方案或解决我的问题。我见过的最常见的事情是使用 onReceive 来设置服务,但我的阅读表明这不再适用于 Oreo 并且是过时的建议。我也看到了一些关于前台服务的东西,但我真的不希望有一个持续的通知来打扰用户。

我还看到有些人说要在 onDestroy 中做一些工作,但这对我也不起作用。我发现的很多东西都说这种行为是“预期行为”,因为系统假设如果一个应用程序被刷掉,用户不再希望它做任何事情。我不希望这种情况发生,并且必须有某种解决方法,因为来自其他应用程序的提醒和通知能够通过。

任何帮助将不胜感激,我已经为此苦苦挣扎了很长时间。我将在下面发布设置警报的代码,以及设置通知通道和 BroadcastReceiver 类的代码。

顺便说一句,我的测试设备是搭载 Android 9 的 Pixel 2XL。

//method to save preferences when the user clicks "SAVE"
    private fun saveData() {

        if (NOTIFICATIONS_PER_DAY > 0) {
            setAlarms()
        } else {
            clearAlarms() //clearing if the user is removing notifications
        }

        val sharedPreferences = activity!!.getSharedPreferences(SHARED_PREFS, MODE_PRIVATE)
        val editor = sharedPreferences.edit()

        editor.putString(THEME_PREF, THEME_SELECTED)
        editor.putInt(NOTS_PREF, NOTIFICATIONS_PER_DAY)

        editor.apply()

        Toast.makeText(context, "Settings saved", Toast.LENGTH_SHORT).show()
    }//saveData method

    //method to set repeating notification alarms (random times)
    private fun setAlarms() {
        //clearing any previously saved alarms to prevent tons of extra
        clearAlarms()
        calList.clear()


        var hour: Int
        var minute: Int

        for (i in 0 until (NOTIFICATIONS_PER_DAY)) {
            val hourRand = (0..23).random()
            val minuteRand = (0..59).random()

            hour = hourRand
            minute = minuteRand
            val cal = Calendar.getInstance()
            cal.set(Calendar.HOUR_OF_DAY, hour)
            cal.set(Calendar.MINUTE, minute)
            cal.set(Calendar.SECOND, 0)

            calList.add(cal)
        }//for

        var i = 0
        for (cal in calList) {
            val alarmManager = context!!.getSystemService(Context.ALARM_SERVICE) as AlarmManager
            val intent = Intent(context, AlertReceiver::class.java)
            val pendingIntent = PendingIntent.getBroadcast(context, i, intent, 0)

            alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.timeInMillis, AlarmManager.INTERVAL_DAY, pendingIntent)
            println(i)
            i++
        }//for

    }//setAlarms method
class BetterDays : Application() {

    override fun onCreate() {
        super.onCreate()
        createNotificationChannels()
    }

    private fun createNotificationChannels() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel1 = NotificationChannel(CHANNEL_1_ID, "Quote Channel", NotificationManager.IMPORTANCE_DEFAULT).apply { description = "New quotes notification" }
            channel1.enableLights(true)
            channel1.enableVibration(true)
            //channel1.description = "New quotes notification"

/*            val channel2 = NotificationChannel(CHANNEL_2_ID, "New Quote!", NotificationManager.IMPORTANCE_DEFAULT)
            channel2.enableLights(true)
            channel2.enableVibration(true)
            channel2.description = "New quotes notification" */

            val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            manager.createNotificationChannel(channel1)
            //manager.createNotificationChannel(channel2)
        }

    }//createNotificationChannels method

    companion object {

        val CHANNEL_1_ID = "quotes notification"
        val CHANNEL_2_ID = "quotes notification 2"
    }
}
class AlertReceiver : BroadcastReceiver() {

    private var notificationManager: NotificationManagerCompat? = null
    private var theContext: Context? = null

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

        notificationManager = NotificationManagerCompat.from(context)
        theContext = context
        sendOnChannel1()
    }//onReceive method

    private fun sendOnChannel1() {
        val title = "New Quote Available"
        val message = "Come check it out!"

        var index: Int = 0
        if(quotesList.size != 0) {
            index = Random.nextInt(quotesList.size)
        }//if
        quoteText = quotesList[index]
        speakerText = speakersList[index]

        quoteTextView?.text = quotesList[index]
        speakerTextView?.text = speakersList[index]


        val intent = Intent(theContext!!, MainActivity::class.java)
        intent.putExtra("From", "quotesFragment")

        val pendingIntent: PendingIntent = PendingIntent.getActivity(theContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)

        val notification = NotificationCompat.Builder(theContext!!, CHANNEL_1_ID)
                .setSmallIcon(R.drawable.ic_quotes)
                .setContentTitle(title)
                .setContentText(message)
                .setAutoCancel(true)
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setCategory(NotificationCompat.CATEGORY_MESSAGE)
                .setContentIntent(pendingIntent)
                .build()

        val id = createID()

        notificationManager!!.notify(id, notification)

    }//sendOnChannel1 method

/*    //for future functionality
    fun sendOnChannel2() {
        val title = "Title"
        val message = "Message"

        val notification = NotificationCompat.Builder(theContext!!, CHANNEL_2_ID)
                .setSmallIcon(R.drawable.ic_quotes)
                .setContentTitle(title)
                .setContentText(message)
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setCategory(NotificationCompat.CATEGORY_MESSAGE)
                .build()

        notificationManager!!.notify(2, notification)

    }//sendOnChannel2 method*/

    //method to generate a unique ID
    private fun createID(): Int{
        val now = Date()
        val id = Integer.parseInt(SimpleDateFormat("ddHHmmss", Locale.US).format(now))
        return id
    }//createID method
}//AlertReceiver class

标签: androidkotlinnotificationsbroadcastreceiveralarmmanager

解决方案


一些带有自己修改过的 android 系统的中国设备,因此当从最近的应用程序托盘中滑动应用程序时,您的应用程序将被终止(类似于强制停止)。由于每个任务都在后台运行,比如服务,乔布斯会被应用程序杀死。即使是高优先级 FCM 也看不到中文 ROM 中的日光。

你可以在这里阅读:https ://medium.com/mindorks/enable-background-services-in-chinese-roms-32e73dfba1a6

也许可以提供帮助;)


推荐阅读