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

Android Studio中每日定时通知调度功能失效问题求助

解决Android每日定时通知调度失效的问题

我看了你贴的代码,这里有几个关键问题导致通知功能无法正常运行,咱们一步步来修复:

1. PendingIntent的Flag兼容问题(Android 12+)

你创建PendingIntent时用的是0,在Android 12(API 31)及以上版本,必须指定FLAG_IMMUTABLE或FLAG_MUTABLE,否则会抛出异常。建议用FLAG_IMMUTABLE(因为你的广播不需要修改Intent内容):

修改MainActivity和MyService里的PendingIntent创建代码:

pendingIntent = PendingIntent.getBroadcast(this, 0, myIntent, PendingIntent.FLAG_IMMUTABLE);

如果你的targetSdkVersion低于31,也可以加上FLAG_UPDATE_CURRENT确保Intent更新:

pendingIntent = PendingIntent.getBroadcast(this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT | (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ? PendingIntent.FLAG_IMMUTABLE : 0));

2. Intent Action设置顺序错误

在MainActivity的startAlarm方法里,你先创建PendingIntent再给Intent设置Action,这会导致PendingIntent里的Intent没有携带Action,Receiver里的intent.getAction().equals("MY_NOTIFICATION_MESSAGE")判断永远不成立,通知不会触发。要先设置Action,再创建PendingIntent:

myIntent = new Intent(MainActivity.this,AlarmNotificationReceiver.class);
myIntent.setAction("MY_NOTIFICATION_MESSAGE"); // 先设置Action
pendingIntent = PendingIntent.getBroadcast(this,0,myIntent,PendingIntent.FLAG_IMMUTABLE);

MyService里的startAlarm方法也要做同样的修改。

3. API 26+必须创建NotificationChannel

从Android 8.0(API 26)开始,所有通知都必须属于一个NotificationChannel,否则通知不会显示。在AlarmNotificationReceiver的onReceive方法开头添加:

// 创建NotificationChannel(API 26+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    String channelId = "daily_alarm_channel";
    String channelName = "每日通知";
    NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT);
    channel.enableVibration(true);
    NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.createNotificationChannel(channel);
    // 给Builder设置ChannelId
    builder.setChannelId(channelId);
}

4. BootReceiver启动服务的兼容性问题(Android 8+)

Android 8.0之后后台启动服务会被限制,不能直接用context.startService(i),需要用startForegroundService,同时MyService必须在启动后5秒内调用startForeground显示前台通知:

首先在AndroidManifest.xml里添加前台服务权限:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

修改BootReceiver的onReceive方法:

public void onReceive(Context context, Intent intent) {
    if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
        Intent i = new Intent(context, MyService.class);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(i);
        } else {
            context.startService(i);
        }
        Toast.makeText(context, "Booting Completed", Toast.LENGTH_LONG).show();
    }
}

然后修改MyService的onCreate方法,添加前台通知:

@Override
public void onCreate() {
    super.onCreate();
    // 创建前台通知(API 26+需要Channel)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        String channelId = "service_channel";
        NotificationChannel channel = new NotificationChannel(channelId, "后台服务", NotificationManager.IMPORTANCE_LOW);
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        manager.createNotificationChannel(channel);

        Notification notification = new Notification.Builder(this, channelId)
                .setContentTitle("服务运行中")
                .setContentText("正在维护定时通知")
                .setSmallIcon(R.mipmap.ic_launcher)
                .build();
        startForeground(1, notification);
    }
    startAlarm(true,true);
}

5. 避免PendingIntent冲突

MainActivity和MyService里创建的PendingIntent用的是同一个requestCode(0),可能会互相覆盖。建议给它们设置不同的requestCode,比如MainActivity用1,MyService用2:

MainActivity里:

pendingIntent = PendingIntent.getBroadcast(this, 1, myIntent, PendingIntent.FLAG_IMMUTABLE);

MyService里:

pendingIntent = PendingIntent.getBroadcast(this, 2, myIntent, PendingIntent.FLAG_IMMUTABLE);

6. 处理当前时间已过设置时间的情况

如果当前时间已经超过了你设置的17:12或18:45,setRepeating会在第二天的同一时间才触发通知。如果你希望如果当前时间已过,就立即触发一次,可以添加判断:

Calendar calendar= Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,17);
calendar.set(Calendar.MINUTE, 12);
calendar.set(Calendar.SECOND, 0); // 加上秒数更精确

// 如果当前时间已过设置时间,加一天
if (calendar.getTimeInMillis() < System.currentTimeMillis()) {
    calendar.add(Calendar.DAY_OF_YEAR, 1);
}

最后检查配置

  • 去掉MyService里无效的android:permission="TODO"配置
  • 确保测试时先手动点击按钮触发一次,验证通知是否弹出,再测试开机自启和每日重复功能

把这些修改都做完之后,你的定时通知应该就能正常工作了。

内容的提问来源于stack exchange,提问作者GinnyWeasley

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:04:47