Я пишу простое приложение, которое устанавливает до 8 случайных, повторяет сигналы тревоги, отправляет уведомление, а затем генерирует цитату, когда пользователь нажимает на уведомление. Кажется, что все это работает должным образом, когда приложение работает, но когда приложение удаляется из последних приложений или принудительно закрывается, уведомления не работают.
Я изучил результаты своих исследований за последние несколько дней и не могу найти решение, которое является текущим или решает мою проблему. Самое распространенное, что я видел, - это использование onReceive для настройки службы, но мои показания показали, что это больше не работает с Oreo и является устаревшим советом. Я также видел кое-что о службах переднего плана, но я действительно не хочу получать постоянное уведомление, беспокоящее пользователя.
Я также видел, как некоторые люди говорят, что они работают в onDestroy, но это тоже не сработало для меня. Многое из того, что я обнаружил, говорит, что такое поведение - это «ожидаемое поведение», так как система предполагает, что если приложение удаляется, пользователь больше не хочет, чтобы оно что-то делало. Я не хочу, чтобы это происходило, и должен быть какой-то обходной путь, так как напоминания и уведомления из других приложений могут проходить.
Любая помощь будет принята с благодарностью, я давно с этим борюсь. Ниже выложу свой код для настройки сигналов тревоги, а также код для настройки каналов уведомлений и класса BroadcastReceiver.
Кстати, мое тестовое устройство - Pixel 2XL с Android 9.
//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