Android Studio应用定时通知无法正常触发问题求助
Android定时通知触发异常求助
开发Android应用时遇到定时通知触发异常:要么设置后立即触发,要么完全不发送通知。目前已成功创建通知渠道,但通知始终无法按时触发。
逻辑流程:启动Service从JSON读取数据(此环节正常),校验处理后调用setScheduleForINI(separateTime(iniTime), remTime)方法,其中iniTime为通知触发时间(HH:MM格式),remTime为通知间隔(分钟格式)。
定时任务设置逻辑
import android.app.AlarmManager import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent import android.app.Service import android.content.Context import android.content.Intent import android.os.Build import android.os.IBinder import android.widget.Toast import androidx.annotation.RequiresApi import androidx.core.app.NotificationCompat import java.text.SimpleDateFormat import java.util.Calendar import java.util.Date import java.util.Locale @Suppress("PrivatePropertyName") class AlarmService : Service() { private val logShow = LogShow() private val jsonManage = JsonManage() companion object { private const val CHANNEL_ID = "SonogiaAlarmChannel" private const val CHANNEL_NAME = "Sonogia" } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { return START_STICKY } override fun onBind(intent: Intent?): IBinder? { return null } override fun onCreate() { super.onCreate() createNotificationChannel() checkJsonGlobalSettings() } private fun createNotificationChannel() { val iniChannel = NotificationChannel( CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH ).apply { description = "Notificaciones de Sonogia" enableLights(true) enableVibration(true) setSound(null, null) lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC setShowBadge(false) } val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(iniChannel) logShow.logShowMsg("AlarmBGService", "Canal de notificaciones creado") } private fun checkJsonGlobalSettings() { logShow.logShowMsg("AlarmBGService", "Revisando configuracion") if (!jsonManage.globalCheck(this)) { logShow.logShowMsg("AlarmBGService", "Formato diario resibido") val date = Date() val dayOfWeek = SimpleDateFormat("EEEE", Locale.getDefault()).format(date) val alarmTimes = jsonManage.checkJsonAlarms(this, dayOfWeek) if (alarmTimes != null) { setNotification(alarmTimes[0], alarmTimes[1], alarmTimes[2]) } else { Toast.makeText(this, "No hay alarmas configuradas", Toast.LENGTH_SHORT).show() } } else { logShow.logShowMsg("AlarmBGService", "Formato Global resibido") val alarmTimes = jsonManage.checkJsonAlarms(this, "Global") if (alarmTimes != null) { setNotification(alarmTimes[0], alarmTimes[1], alarmTimes[2]) } else { Toast.makeText(this, "No hay alarmas configuradas", Toast.LENGTH_SHORT).show() } } } private fun setNotification(iniTime: String, remTime: String, wakeTime: String) { logShow.logShowMsg("AlarmBGService", "Configuracion leida: iniTime: $iniTime, remTime: $remTime, wakeTime: $wakeTime") logShow.logShowMsg("AlarmBGService", "Configurando alarmas: INI") setScheduleForINI(separateTime(iniTime), remTime) logShow.logShowMsg("AlarmBGService", "Configurando alarmas: WAKE") // AlarmReceiver.wakeNotification(wakeTime,this) } private fun separateTime(time: String): Array<String> { val parts = time.split(":") logShow.logShowMsg("AlarmBGService", "Hora: ${parts[0]}, Minuto: ${parts[1]}") return parts.toTypedArray() } private fun setScheduleForINI(iniTime: Array<String>, remTime: String) { logShow.logShowMsg("AlarmBGService", "IniHour: ${iniTime[0]}, IniMinute: ${iniTime[1]}") cancelAlarm() // Cancel existing alarm val intent = Intent(applicationContext, NotificationReceiver::class.java) val pendingIntent = PendingIntent.getBroadcast( applicationContext, 1, intent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager val calendar = Calendar.getInstance().apply { timeInMillis = System.currentTimeMillis() set(Calendar.HOUR_OF_DAY, iniTime[0].toInt()) set(Calendar.MINUTE, iniTime[1].toInt()) set(Calendar.SECOND, 0) } logShow.logShowMsg("AlarmBGService", "Agendando a las: ${calendar.timeInMillis}") try { if (remTime.isNotEmpty()) { if (remTime.toInt() != 0) { alarmManager.setInexactRepeating( AlarmManager.RTC_WAKEUP, calendar.timeInMillis, remTime.toLong() * 1000 * 60, pendingIntent ) logShow.logShowMsg("AlarmBGService", "Agendado con intervalo remTime: $remTime") } else { alarmManager.set( AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent ) logShow.logShowMsg("AlarmBGService", "Agendado sin intervalo remTime: $remTime") } } } catch (e: SecurityException) { logShow.logShowMsg("AlarmBGService", "Error al programar la alarma: ${e.message}") } logShow.logShowMsg("AlarmBGService", "Agendado") } private fun cancelAlarm() { val intent = Intent(applicationContext, NotificationReceiver::class.java) val pendingIntent = PendingIntent.getBroadcast( applicationContext, 1, intent, PendingIntent.FLAG_NO_CREATE // Cancel alarm if it exists ) pendingIntent?.let { val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager alarmManager.cancel(it) it.cancel() logShow.logShowMsg("AlarmBGService", "Alarm canceled") } } override fun onDestroy() { super.onDestroy() cancelAlarm() } }
通知创建逻辑
class NotificationReceiver : BroadcastReceiver() { private val logShow = LogShow() companion object{ private const val NOTIFICATION_ID = 1 private const val CHANNEL_ID = "SonogiaAlarmChannel" } @RequiresApi(Build.VERSION_CODES.TIRAMISU) override fun onReceive(context: Context, intent: Intent) { iniNotification(context) val stop = intent?.getStringExtra("A dormir") if (stop == "A dormir"){ logShow.logShowMsg("NotificationReceiver", "Repeticion detenida") Toast.makeText(context, "Buenas noches", Toast.LENGTH_SHORT).show() } } @RequiresApi(Build.VERSION_CODES.TIRAMISU) private fun iniNotification(context: Context) { val iniRemoteViews = RemoteViews(context.packageName, R.layout.notification_layout) iniRemoteViews.setOnClickPendingIntent( R.id.cancel_button, PendingIntent.getBroadcast( context, 0, Intent(context, NotificationReceiver::class.java).putExtra("action", "cancel_rem"), PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) ) val pendingIntent = PendingIntent.getBroadcast( context, 0, Intent(context, NotificationReceiver::class.java).putExtra("A dormir", "A dormir"), PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) val iniNotification = NotificationCompat.Builder(context, CHANNEL_ID) .setContentTitle("Buenas noches") .setContentText("Ha llegado la hora de dormir, te deseamos dulces sueños. Att: Sonogia") .setSmallIcon(R.mipmap.ic_launcher_round) .setCustomContentView(iniRemoteViews) .addAction(0, "A dormir", pendingIntent) val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager manager.notify(NOTIFICATION_ID, iniNotification) logShow.logShowMsg("NotificationReceiver", "IniNotification enviada") } }
已尝试使用setExact等多种AlarmManager方法,调整执行逻辑,前置的JSON读取、参数解析流程均正常,但通知仍无法按时触发,请求协助排查问题。
内容的提问来源于stack exchange,提问作者Yuzel Rose
相关产品推荐
相关产品推荐

