Android 13/12精准定时本地通知失效问题求助
Android 13/12 定时通知不工作的问题排查与修复
你的代码存在多处逻辑和配置错误,直接导致定时通知功能失效,以下是具体问题和修复方案:
关键错误点
- 触发时间计算错误:
AlarmManager.RTC_WAKEUP需要的是从1970年到触发时间的绝对毫秒数,你写的10 * 60 * 1000是相对偏移量,不是绝对时间,系统会认为是1970年的某个时间,自然不会触发。 - Action字符串不匹配:代码里设置的Intent Action是
com.test.ACTION_MY_ALARM,但Manifest里写成了com.text.ACTION_MY_ALARM(test拼写错误),而且Receiver的onReceive方法根本没处理这个Action。 - 权限检查缺失:Android 12及以上使用精确闹钟需要先检查
SCHEDULE_EXACT_ALARM权限,你只声明了权限但没做检查和请求逻辑。 - Receiver逻辑遗漏:
onReceive里没有处理你设置的闹钟Action,就算触发了也不会有任何反馈。 - 冗余配置:添加了不必要的权限(
USE_EXACT_ALARM、SET_ALARM、INTERNET)和进程配置(:remote),增加了不必要的复杂度。
修复后的完整代码示例
1. 修复后的闹钟调度方法
public static void scheduleExactAlarm(Context context) { AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); if (alarmManager == null) { return; } // Android 12+ 检查精确闹钟权限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (!alarmManager.canScheduleExactAlarms()) { // 跳转到应用设置页请求权限 Intent intent = new Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM); intent.setData(Uri.parse("package:" + context.getPackageName())); context.startActivity(intent); return; } } Intent alarmIntent = new Intent(context, MYAlarmReceiver.class); alarmIntent.setAction("com.test.ACTION_MY_ALARM"); PendingIntent pendingIntent = PendingIntent.getBroadcast( context, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE ); // 计算10分钟后的绝对触发时间 long triggerMillis = System.currentTimeMillis() + 10 * 60 * 1000; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { alarmManager.setExactAndAllowWhileIdle( AlarmManager.RTC_WAKEUP, triggerMillis, pendingIntent ); } else { alarmManager.setExact( AlarmManager.RTC_WAKEUP, triggerMillis, pendingIntent ); } }
2. 修复后的广播接收器
public class MYAlarmReceiver extends BroadcastReceiver { private static final String TAG = "AlarmReceiver"; private static final String ACTION_MY_ALARM = "com.test.ACTION_MY_ALARM"; @Override public void onReceive(Context context, Intent intent) { if (intent.getAction() != null) { switch (intent.getAction()) { case ACTION_MY_ALARM: // 触发闹钟时的逻辑:显示Toast+发送通知 Toast.makeText(context, "ALARM FIRED", Toast.LENGTH_LONG).show(); sendNotification(context); break; case "android.app.action.SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED": Toast.makeText(context, "RECEIVED ALARM PERMISSION", Toast.LENGTH_LONG).show(); break; } } } // 发送通知的工具方法 private void sendNotification(Context context) { NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); // Android 8+ 创建通知渠道 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel( "ALARM_CHANNEL", "闹钟通知", NotificationManager.IMPORTANCE_HIGH ); notificationManager.createNotificationChannel(channel); } NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "ALARM_CHANNEL") .setSmallIcon(R.drawable.ic_notification) // 替换成你的通知图标 .setContentTitle("定时闹钟") .setContentText("您设置的定时闹钟已触发!") .setPriority(NotificationCompat.PRIORITY_HIGH); notificationManager.notify(1, builder.build()); } }
3. 修复后的Manifest配置
<receiver android:name=".MYAlarmReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="com.test.ACTION_MY_ALARM" /> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.app.action.SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED" /> </intent-filter> </receiver> <!-- 保留必要权限即可 --> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
额外注意事项
- Android 13+ 需要主动请求
POST_NOTIFICATIONS权限,否则无法发送通知,记得在启动页或者设置页添加权限请求逻辑。 - 移除了
android:process=":remote",除非你明确需要接收器在独立进程运行,否则会导致上下文异常。
内容的提问来源于stack exchange,提问作者Toni
相关产品推荐
相关产品推荐

