Android AlarmManager无法触发通知问题排查求助
通知无法触发的问题排查与修复
你的代码存在多处关键错误,导致通知无法正常触发,具体问题和修复方案如下:
核心错误点
- Notification.kt 文件内容完全错误:你提供的Notification.kt实际上是MainActivity的重复代码,正确的应该是继承
BroadcastReceiver的接收器类,而非Activity。 - 全局常量未定义:代码中使用的
titleExtra、messageExtra、channelID、notificationID这些常量没有声明,会导致编译或运行错误。 - PendingIntent 目标类型不匹配:调用
PendingIntent.getBroadcast()时,目标类应该是广播接收器,但你传入的是错误的Activity类。 - 广播接收器未在Manifest注册:自定义的BroadcastReceiver必须在AndroidManifest.xml中注册,否则系统无法识别并触发它。
- 通知发送逻辑缺失:原代码中没有在广播接收器内构建和发送通知的核心逻辑。
修正后的完整代码
1. 补充MainActivity.kt的常量定义
在MainActivity类外部添加全局常量:
package com.example.firstalarmmanager import android.annotation.SuppressLint import android.app.AlarmManager import android.app.AlertDialog import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent import android.content.Context import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import com.example.firstalarmmanager.databinding.ActivityMainBinding import java.util.Calendar import java.util.Date // 添加全局常量 const val titleExtra = "titleExtra" const val messageExtra = "messageExtra" const val channelID = "channelID" const val notificationID = 101 class MainActivity : AppCompatActivity() { private lateinit var binding : ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) createNotificationChannel() binding.submitButton.setOnClickListener { scheduleNotification() } } @SuppressLint("ScheduleExactAlarm") private fun scheduleNotification() { // 修正Intent目标为广播接收器类 val intent = Intent(applicationContext, NotificationReceiver::class.java) val title = binding.titleET.text.toString() val message = binding.messageET.text.toString() intent.putExtra(titleExtra, title) intent.putExtra(messageExtra, message) val pendingIntent = PendingIntent.getBroadcast( applicationContext, notificationID, intent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager val time = getTime() alarmManager.setExactAndAllowWhileIdle( AlarmManager.RTC_WAKEUP, time, pendingIntent ) showAlert(time, title, message) } private fun showAlert(time: Long, title: String, message: String) { val date = Date(time) val dateFormat = android.text.format.DateFormat.getLongDateFormat(applicationContext) val timeFormat = android.text.format.DateFormat.getTimeFormat(applicationContext) AlertDialog.Builder(this) .setTitle("Notification Scheduled") .setMessage( "Title: $title\nMessage: $message\nAt: ${dateFormat.format(date)} ${timeFormat.format(date)}" ) .setPositiveButton("Okay"){_,_ ->} .show() } private fun getTime(): Long { val minute = binding.timePicker.minute val hour = binding.timePicker.hour val day = binding.datePicker.dayOfMonth val month = binding.datePicker.month val year = binding.datePicker.year val calendar = Calendar.getInstance() calendar.set(year, month, day, hour, minute) return calendar.timeInMillis } private fun createNotificationChannel() { val name = "Notif Channel" val desc = "A Description of the Channel" val importance = NotificationManager.IMPORTANCE_DEFAULT val channel = NotificationChannel(channelID, name, importance) channel.description = desc val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(channel) } }
2. 创建正确的NotificationReceiver.kt(替换原错误的Notification.kt)
package com.example.firstalarmmanager import android.app.Notification import android.app.NotificationManager import android.content.BroadcastReceiver import android.content.Context import android.content.Intent class NotificationReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { context?.let { ctx -> val title = intent?.getStringExtra(titleExtra) ?: "Default Title" val message = intent?.getStringExtra(messageExtra) ?: "Default Message" // 构建通知 val notification = Notification.Builder(ctx, channelID) .setContentTitle(title) .setContentText(message) .setSmallIcon(R.drawable.ic_notification) // 需替换为你的应用图标 .setAutoCancel(true) .build() // 发送通知 val notificationManager = ctx.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.notify(notificationID, notification) } } }
3. 在AndroidManifest.xml中注册广播接收器并添加权限
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.firstalarmmanager"> <!-- Android 12+ 需要的精确闹钟权限 --> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> <!-- 唤醒屏幕权限(可选,用于锁屏时显示通知) --> <uses-permission android:name="android.permission.WAKE_LOCK" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.FirstAlarmManager"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- 注册广播接收器 --> <receiver android:name=".NotificationReceiver" android:exported="false" /> </application> </manifest>
额外注意事项
- 确保你在drawable目录下添加了名为
ic_notification的图标资源,或者替换为你已有的图标。 - 测试时建议设置1分钟后的时间,避免设置过去的时间导致闹钟不触发。
- 部分厂商系统会限制后台应用的广播触发,可将应用加入系统白名单测试。
内容的提问来源于stack exchange,提问作者lapdoggo
相关产品推荐
相关产品推荐

