You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 16:23:13