You need to enable JavaScript to run this app. Android Java实现每日定时通知失败,onTimeSet触发报InputDispatcher错误
优惠活动
大模型
产品
解决方案
定价
更多

Android Java实现每日定时通知失败,onTimeSet触发报InputDispatcher错误

问题根因

  1. 你遇到的Window ... has no registered input channel报错是时序问题导致:onTimeSet()是TimePickerDialog的回调,触发时Dialog还未完成销毁流程,此时你直接执行Activity跳转,SetNotificationActivity被切到后台后,Dialog的输入管道还没来得及注销就被系统回收,触发报错。
  2. 无法收到通知是多版本适配问题导致:PendingIntent合法性、AlarmManager权限与接口适配、通知权限/通道配置不正确都会导致广播不触发、通知无法展示。

修复步骤

1. 修复时序报错

调整跳转逻辑,等待TimePickerDialog完全销毁后再执行页面跳转,修改SetNotificationActivity的对应代码:

@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
    Calendar c = Calendar.getInstance();
    c.set(Calendar.HOUR_OF_DAY, hourOfDay);
    c.set(Calendar.MINUTE, minute);
    c.set(Calendar.SECOND, 0); // 新增:对齐整分钟,避免秒级误差
    startAlarm(c);
    // 新增:延迟300ms跳转,等待Dialog销毁完成
    new Handler(Looper.getMainLooper()).postDelayed(() -> {
        startActivity(new Intent(SetNotificationActivity.this, HomeActivity.class));
        finish();
    }, 300);
}

private void startAlarm(Calendar c) {
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(this, AlertReceiver.class);
    // 修复:安卓12及以上要求PendingIntent必须指定可变性标识
    int pendingFlag = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0;
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, pendingFlag);

    if (c.before(Calendar.getInstance()))
        c.add(Calendar.DATE, 1);

    // 修复:高版本安卓用精确闹钟接口,避免低电耗模式拦截
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
    } else {
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
    }
    // 移除原有跳转逻辑,移到onTimeSet的延迟任务中
}

同时调整跳过按钮的跳转顺序,避免类似时序问题:

skip_btn.setOnClickListener(v -> {
    startActivity(new Intent(SetNotificationActivity.this, HomeActivity.class));
    finish();
});

2. 修复广播内PendingIntent适配

修改AlertReceiver中的PendingIntent配置,适配高版本安卓要求:

@Override
public void onReceive(Context context, Intent intent) {
    Intent intent1 = new Intent(context, SplashScreenActivity.class);
    intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

    // 修复:适配高版本PendingIntent标识要求
    int pendingFlag = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? 
        PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT;
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 100, intent1, pendingFlag);

    NotificationHelper notificationHelper = new NotificationHelper(context);
    NotificationCompat.Builder nb = notificationHelper.getChannelNotification();
    nb.setContentIntent(pendingIntent); // 恢复点击跳转逻辑,可选
    notificationHelper.getManager().notify(1, nb.build());

    // 新增:如果需要每日重复提醒,每次收到广播后重新设置下一天的闹钟
    Calendar nextAlarm = Calendar.getInstance();
    nextAlarm.add(Calendar.DATE, 1);
    // 此处复用SetNotificationActivity中的闹钟设置逻辑即可
}

3. 补充权限与配置

在AndroidManifest.xml中添加必要权限:

<!-- 开机自启权限,重启设备后闹钟不会丢失 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- 通知振动权限 -->
<uses-permission android:name="android.permission.VIBRATE" />
<!-- 安卓13+ 通知推送权限,需要动态申请 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- 安卓12+ 精确闹钟权限 -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />

<!-- 确保AlertReceiver已在清单文件中注册 -->
<receiver android:name=".AlertReceiver" />

4. 确认通知通道配置

安卓8.0及以上系统必须创建合法的通知通道才能推送通知,确保你的NotificationHelper中包含类似通道创建逻辑:

public class NotificationHelper extends ContextWrapper {
    public static final String CHANNEL_ID = "daily_notify_channel";
    private NotificationManager manager;

    public NotificationHelper(Context base) {
        super(base);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                CHANNEL_ID,
                "每日提醒",
                NotificationManager.IMPORTANCE_HIGH
            );
            channel.enableLights(true);
            channel.enableVibration(true);
            getManager().createNotificationChannel(channel);
        }
    }

    public NotificationCompat.Builder getChannelNotification() {
        return new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_notification) // 替换为你的通知图标
            .setContentTitle("每日提醒")
            .setContentText("你设置的提醒时间到了")
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setAutoCancel(true);
    }

    public NotificationManager getManager() {
        if (manager == null) {
            manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        }
        return manager;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 16:27:04