android - 刷掉应用程序时通知不起作用
问题描述
我正在编写一个简单的应用程序,它最多设置 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
解决方案
一些带有自己修改过的 android 系统的中国设备,因此当从最近的应用程序托盘中滑动应用程序时,您的应用程序将被终止(类似于强制停止)。由于每个任务都在后台运行,比如服务,乔布斯会被应用程序杀死。即使是高优先级 FCM 也看不到中文 ROM 中的日光。
你可以在这里阅读:https ://medium.com/mindorks/enable-background-services-in-chinese-roms-32e73dfba1a6
也许可以提供帮助;)
推荐阅读
- c - 在(空)框架中找不到“SLSIsSuppressedByScreenTime”
- c++ - 将代码移动到函数中时,在 DLL“myApp.exe”中找不到错误 0xC0000138 序号
- algorithm - 找到转换为回文的最低成本
- django - 如何序列化具有多个外键的模型?
- go - 尝试使用 close(ch) 结束 goroutine 但最终无限运行
- javascript - Javascript - 给第一个 X div 其他类
- regex - Unmatched ) 在 Regex grep 期间
- c# - Convert.ToChar() 失败
- php - 添加表单标签时,我的 ajax 调用不起作用,为什么?
- android - 谷歌地图在调试和发布 APK 后不显示