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

如何在Xamarin跨平台中实现应用不在设备最近历史时显示本地通知

嘿,我来帮你搞定这个需求!要在应用完全关闭(甚至不在最近历史列表里)的时候触发本地通知,你当前用的Device.StartTimer肯定不行——这玩意儿只有应用在前台跑的时候才会工作,应用一关掉定时器就歇菜了。咱们得用平台原生的后台调度机制,结合Xamarin.Forms的依赖服务来实现,下面分步骤给你捋清楚:

核心思路

Xamarin.Forms本身没有跨平台的后台定时任务API,所以得针对Android和iOS分别实现原生的调度逻辑,再通过依赖服务统一调用,这样才能在应用关闭时依然触发通知。

步骤1:定义跨平台接口

首先在共享项目里定义一个统一的接口,用来调用不同平台的通知调度功能:

public interface IAlarmScheduler
{
    // 调度重复触发的通知(比如每5分钟一次)
    void ScheduleRepeatingNotification(TimeSpan interval);
    // 取消所有已调度的通知
    void CancelAllNotifications();
}
步骤2:Android平台实现

Android上我们用AlarmManager实现后台调度,搭配BroadcastReceiver来触发通知。

2.1 创建广播接收器

在Android项目里新建AlarmReceiver.cs:

[BroadcastReceiver(Enabled = true, Exported = true)]
[IntentFilter(new[] { "com.yourcompany.yourapp.NOTIFICATION_ALARM" })]
public class AlarmReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        // 收到广播后显示本地通知
        ShowNotification(context);
    }

    private void ShowNotification(Context context)
    {
        var notificationManager = NotificationManagerCompat.From(context);
        
        // 构建通知内容
        var notification = new NotificationCompat.Builder(context, "TIMER_NOTIFICATION_CHANNEL")
            .SetSmallIcon(Resource.Drawable.ic_notification)
            .SetContentTitle("定时提醒")
            .SetContentText("这是应用关闭时触发的通知")
            .SetPriority(NotificationCompat.PriorityDefault)
            .Build();

        // 显示通知(注意Android 8.0+必须先创建通知通道)
        notificationManager.Notify(1, notification);
    }
}

2.2 实现调度接口

在Android项目里创建AlarmScheduler.cs:

public class AlarmScheduler : IAlarmScheduler
{
    public void ScheduleRepeatingNotification(TimeSpan interval)
    {
        var context = Android.App.Application.Context;
        var alarmManager = (AlarmManager)context.GetSystemService(Context.AlarmService);
        
        var intent = new Intent("com.yourcompany.yourapp.NOTIFICATION_ALARM");
        var pendingIntent = PendingIntent.GetBroadcast(context, 0, intent, PendingIntentFlags.UpdateCurrent | PendingIntentFlags.Immutable);

        // Android 12+需要用精确闹钟权限,适配不同版本
        if (Build.VERSION.SdkInt >= BuildVersionCodes.S)
        {
            alarmManager.SetExactAndAllowWhileIdle(AlarmManager.RtcWakeup, 
                SystemClock.ElapsedRealtime() + interval.TotalMilliseconds, 
                pendingIntent);
        }
        else
        {
            alarmManager.SetRepeating(AlarmManager.RtcWakeup, 
                SystemClock.ElapsedRealtime() + interval.TotalMilliseconds, 
                interval.TotalMilliseconds, 
                pendingIntent);
        }
    }

    public void CancelAllNotifications()
    {
        var context = Android.App.Application.Context;
        var intent = new Intent("com.yourcompany.yourapp.NOTIFICATION_ALARM");
        var pendingIntent = PendingIntent.GetBroadcast(context, 0, intent, PendingIntentFlags.UpdateCurrent | PendingIntentFlags.Immutable);
        
        var alarmManager = (AlarmManager)context.GetSystemService(Context.AlarmService);
        alarmManager.Cancel(pendingIntent);
    }
}

2.3 配置权限和通知通道

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

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

然后在MainActivity的OnCreate方法里创建通知通道(Android 8.0+必填):

protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    
    if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
    {
        var channel = new NotificationChannel("TIMER_NOTIFICATION_CHANNEL", "定时通知", NotificationImportance.Default)
        {
            Description = "应用关闭时的定时提醒通知"
        };
        var notificationManager = GetSystemService(NotificationService) as NotificationManager;
        notificationManager.CreateNotificationChannel(channel);
    }
}
步骤3:iOS平台实现

iOS上我们用UNUserNotificationCenter结合时间间隔触发器来实现后台通知调度。

3.1 实现调度接口

在iOS项目里创建AlarmScheduler.cs:

public class AlarmScheduler : IAlarmScheduler
{
    public void ScheduleRepeatingNotification(TimeSpan interval)
    {
        UNUserNotificationCenter.Current.RequestAuthorization(UNAuthorizationOptions.Alert | UNAuthorizationOptions.Sound, (granted, error) =>
        {
            if (granted)
            {
                var content = new UNMutableNotificationContent();
                content.Title = "定时提醒";
                content.Body = "这是应用关闭时触发的通知";
                content.Sound = UNNotificationSound.Default;

                // 创建重复触发的时间间隔触发器
                var trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(interval.TotalSeconds, repeats: true);
                var request = UNNotificationRequest.FromIdentifier("RepeatingTimerNotification", content, trigger);

                UNUserNotificationCenter.Current.AddNotificationRequest(request, (error) =>
                {
                    if (error != null)
                    {
                        // 处理通知添加失败的情况
                    }
                });
            }
        });
    }

    public void CancelAllNotifications()
    {
        UNUserNotificationCenter.Current.RemoveAllPendingNotificationRequests();
    }
}

3.2 配置iOS权限

在Info.plist中添加通知权限描述:

<key>NSUserNotificationUsageDescription</key>
<string>需要发送定时通知提醒您相关事项</string>
<key>UIBackgroundModes</key>
<array>
    <string>remote-notification</string>
</array>
步骤4:在共享项目中调用

修改你的MainPage.cs,替换原来的Device.StartTimer逻辑,改为调用依赖服务的调度方法:

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
        
        // 调度每5分钟一次的通知
        var scheduler = DependencyService.Get<IAlarmScheduler>();
        scheduler.ScheduleRepeatingNotification(TimeSpan.FromMinutes(5));
    }

    // 如需取消通知,可调用此方法
    private void CancelNotifications()
    {
        var scheduler = DependencyService.Get<IAlarmScheduler>();
        scheduler.CancelAllNotifications();
    }
}
关键注意点
  • Android 12+需要用户手动开启SCHEDULE_EXACT_ALARM权限(可以引导用户到应用设置页面开启)
  • iOS如果用户从最近列表彻底划掉应用,重复通知可能会停止,这是iOS的系统限制,无法绕过
  • 测试时一定要把应用完全关闭(从最近列表移除),等待设定的时间看是否触发通知

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:58:24