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

MAUI前台服务Android 8.1正常运行,Android 13无法工作求配置方案

MAUI前台服务在Android 13无法运行的解决方案

我开发了一个MAUI前台服务,该服务在Android 8.1模拟器中可正常运行,但在Android 13模拟器中无法工作。以下是我的实现代码:

using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.OS;

//Tiene que pertenecer al namespace raíz para poder tener acceso a Android.Content y otros
//recursos.
namespace GTS.CMMS.RegistroHorario.UI.Maui;

[Service]
public class AlarmasForegroundService : Service, IAlarmasForegroundService, IDisposable
{
    #region variables de clase
    //Class with PeriodicTimer() to check conditions periodically.
    private IServicioAlarmas _servicioAlarmas;

    private string NOTIFICATION_CHANNEL_ID = "1000";
    private int NOTIFICATION_ID = 1;
    private string NOTIFICATION_CHANNEL_NAME = "notification";
    private NotificationManager _notificationManager;
    #endregion variables de clase

    #region constructores
    public AlarmasForegroundService()
    {
        _servicioAlarmas = new ServicioAlarmas(new LocalizadorHelper());
        _servicioAlarmas.NotificacionNecesariaEvent += OnNotificacionNecesariaHandler;
    }
    #endregion constructores

    #region creación del foreground
    private void StartForegroundService()
    {
        _notificationManager = (GetSystemService(Context.NotificationService) as NotificationManager)!;

        createNotificationChannel(_notificationManager);

        Notification notification = new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
            .SetAutoCancel(false)
            .SetOngoing(false)
            .Build();
        StartForeground(NOTIFICATION_ID, notification);
    }

    private NotificationChannel? createNotificationChannel(NotificationManager notificationMnaManager)
    {
        if (Build.VERSION.SdkInt < BuildVersionCodes.O) return null;

        NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationImportance.Default);
        notificationMnaManager.CreateNotificationChannel(channel);

        return channel;
    }

    public override IBinder OnBind(Intent intent)
    {
        return null;
    }

    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {
        StartForegroundService();
        return StartCommandResult.NotSticky;
    }
    #endregion creación del foregroud

    public override void OnCreate()
    {
        base.OnCreate();
        _servicioAlarmas.Iniciar();
    }

    public override void OnDestroy()
    {
        _servicioAlarmas.NotificacionNecesariaEvent -= OnNotificacionNecesariaHandler;

        _servicioAlarmas.DetenerAsync();
        base.OnDestroy();
    }

    #region implementación del intefaz IAlarmasForegroundService
    public void Iniciar()
    {
        var intent = new Intent(Android.App.Application.Context, typeof(AlarmasForegroundService));
        Android.App.Application.Context.StartForegroundService(intent);
    }

    public void Detener()
    {
        var intent = new Intent(Android.App.Application.Context, typeof(AlarmasForegroundService));
        Android.App.Application.Context.StopService(intent);
    }
    #endregion implementación del intefaz IAlarmasForegroundService

    #region manejadores de eventos
    private void OnNotificacionNecesariaHandler(string paramStrMensajeAlarma)
    {
        Notification notification = new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
            .SetContentTitle("Servicio trabajando (Título)")
            .SetContentText(paramStrMensajeAlarma)
            .SetSmallIcon(Resource.Drawable.abc_ab_share_pack_mtrl_alpha)
            .SetDefaults(NotificationDefaults.Sound | NotificationDefaults.Vibrate)
            .SetAutoCancel(false)
            .SetOngoing(true)
            .Build();

        _notificationManager.Notify(NOTIFICATION_ID, notification);
    }
    #endregion manejadores de eventos
}

针对Android 13,你需要做以下几项关键配置调整:

  • 添加POST_NOTIFICATIONS权限
    Android 13(API 33)引入了单独的通知权限,必须在AndroidManifest.xml中声明该权限,并且在运行时主动请求用户授权:

    1. 在Platforms/Android/AndroidManifest.xml中添加:
      <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
      
    2. 在启动前台服务前,检查并请求权限:
      if (Build.VERSION.SdkInt >= BuildVersionCodes.Tiramisu)
      {
          if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.PostNotifications) != Permission.Granted)
          {
              ActivityCompat.RequestPermissions(this, new[] { Manifest.Permission.PostNotifications }, 1001);
          }
      }
      
  • 修复前台服务通知的必填项
    Android 13要求前台服务的通知必须包含小图标,你当前在StartForegroundService方法中创建的初始通知没有设置SetSmallIcon,这会导致服务启动失败。修改该通知的构建代码:

    Notification notification = new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
        .SetSmallIcon(Resource.Drawable.abc_ab_share_pack_mtrl_alpha) // 添加此行
        .SetAutoCancel(false)
        .SetOngoing(false)
        .Build();
    
  • 配置前台服务类型(可选但推荐)
    如果你的服务涉及特定功能(比如位置跟踪、媒体播放等),需要在[Service]标签中指定ForegroundServiceType,例如:

    [Service(ForegroundServiceType = ForegroundService.Type.None)] // 根据实际功能选择对应类型
    

    常用类型包括ForegroundService.Type.Location、ForegroundService.Type.MediaPlayback等,若只是定时任务,使用None即可。

  • 确保服务启动逻辑合规
    Android 13对后台启动服务的限制更严格,务必确保你是在前台上下文(比如Activity)中调用StartForegroundService,避免在纯后台场景启动服务。

内容的提问来源于stack exchange,提问作者Álvaro García

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 04:53:07