首页 > 解决方案 > 在 xamarin 表单中关闭应用程序时无法显示通知

问题描述

我正在尝试实现一个后台服务,它会不断地通知我。因此,我正在使用警报管理器和广播接收器。这是我的广播接收器代码

[BroadcastReceiver(Enabled = true)]
    [IntentFilter(new string[] {PeriodicService.AlarmService, "android.intent.action.BOOT_COMPLETED" }, Priority = (int)IntentFilterPriority.LowPriority)]
    public class BackgroundReceiver : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            PowerManager pm = (PowerManager)context.GetSystemService(Context.PowerService);
            PowerManager.WakeLock wakeLock = pm.NewWakeLock(WakeLockFlags.Partial, "BackgroundReceiver");
            wakeLock.Acquire();
            Device.StartTimer(new TimeSpan(0, 0, 10), () =>
            {
                // do something every 60 seconds
                Device.BeginInvokeOnMainThread(() =>
                {

                    Toast.MakeText(Android.App.Application.Context, "Hi when app opened", ToastLength.Short).Show();
                    NotificationCenter.NotifyNotificationTapped(intent);
                   
                    var alarmAttributes = new AudioAttributes.Builder()
                                      .SetContentType(AudioContentType.Sonification)
                                      .SetUsage(AudioUsageKind.Alarm)
                                      .Build();

                   // var alarmUri = Android.Net.Uri.Parse("Resources/Audio/AlarmSound.wav");
                    NotificationCenter.Current.Show((notification) => notification
                           .WithScheduleOptions((schedule) => schedule
                           .Build())
                           
                           .WithAndroidOptions((android) => android
                                .WithAutoCancel(true)
                                .WithChannelId("General")
                                
                                .WithPriority(Plugin.LocalNotification.NotificationPriority.High)
                                .Build())
                           .WithiOSOptions((ios) => ios
                               .ShouldPlayForegroundSound(true)
                               .Build())
                           .WithReturningData("Dummy Data")
                           .WithTitle("Test Title")
                           .WithDescription("Test Description")
                           .WithNotificationId(100)
                           .Create());
                    Toast.MakeText(Android.App.Application.Context, "HI", ToastLength.Short).Show();
                    MessagingCenter.Send<object, string>(this, "UpdateLabel", "Hello from Android");
                });
                return true; // runs again, or false to stop
            });

            wakeLock.Release();
        }
    }

这是我的后台服务代码

[Service]
    public class PeriodicService : Service
    {
        public override IBinder OnBind(Intent intent)
        {
            return null;
        }

        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            // From shared code or in your PCL
            MessagingCenter.Send<object, string>(this, "UpdateLabel", "Hello from Android");
       
            Device.StartTimer(new TimeSpan(0, 0, 10), () =>
            {
                // do something every 60 seconds
                Device.BeginInvokeOnMainThread(() =>
                {
                    Toast.MakeText(Android.App.Application.Context, "Hi when app closed", ToastLength.Short).Show();
                  
                });
                return true; // runs again, or false to stop
            });
            return StartCommandResult.Sticky;
        }

    }

这是我的主要活动代码

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
       protected override void OnCreate(Bundle savedInstanceState)
    {
      

        base.OnCreate(savedInstanceState);


        global::Xamarin.Essentials.Platform.Init(this, savedInstanceState);

        ZXing.Net.Mobile.Forms.Android.Platform.Init();
        

        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
        global::ZXing.Net.Mobile.Forms.Android.Platform.Init();

        LoadApplication(new App());
        Intent alarmIntent = new Intent(Application.Context, typeof(BackgroundReceiver));
        BackgroundReceiver myreceiver = new BackgroundReceiver();
        RegisterReceiver(myreceiver, new IntentFilter("android.intent.action.BOOT_COMPLETED"));
        //StartService(new Intent(this, typeof(PeriodicService)));
        // CreateNotificationChannel();
        if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
        {
            //DispatchNotificationThatServiceIsRunning();
            //StartForegroundService(Intent);
            StartService(new Intent(this, typeof(PeriodicService)));
        }
        else
        {
            StartService(new Intent(this, typeof(PeriodicService)));
        }

       
        //alarmIntent.PutExtra("message", "This is my test message!");
        //alarmIntent.PutExtra("title", "This is my test title!");
        //PendingIntent pendingIntent = PendingIntent.GetBroadcast(Application.Context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
        //AlarmManager alarmManager = (AlarmManager)Application.Context.GetSystemService(Context.AlarmService);
        //alarmManager.SetAndAllowWhileIdle(AlarmType.RtcWakeup, DateTime.Now.Millisecond + 5000, pendingIntent);

    }

这是我在清单中的代码

<application android:theme="@style/MainTheme" android:usesCleartextTraffic="true" android:allowBackup="false" android:label="myproject">
        <receiver android:name=".BackgroundReceiver" android:enabled="true" android:exported="true" android:process=":remote" android:label="myproject" />
    </application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.FLASHLIGHT" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>

这是我请求许可的代码

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            global::Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
            global::ZXing.Net.Mobile.Android.PermissionsHandler.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }

我经历了许多解决方案,但没有任何帮助。这些是我经历过的链接

Android - 应用程序关闭后,AlarmManager 不工作

应用程序关闭时警报管理器不起作用

我也尝试使用前台服务,这是我的服务代码

  public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            // From shared code or in your PCL
            MessagingCenter.Send<object, string>(this, "UpdateLabel", "Hello from Android");
            
            
                    CreateNotificationChannel();
                    DispatchNotificationThatServiceIsRunning();

            return StartCommandResult.Sticky;
        }
        public void DispatchNotificationThatServiceIsRunning()
        {
            
            NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(this)
            .SetDefaults((int)NotificationDefaults.All)

            .SetVibrate(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 })
            .SetSound(null)

            .SetPriority(NotificationCompat.PriorityHigh)
            .SetAutoCancel(false)
            .SetSmallIcon(Resource.Drawable.notification_icon_background)
            .SetContentTitle("test")
            .SetContentText("service started")
            .SetOngoing(true);
            
            Notification bui = mBuilder.Build();
            NotificationManager notificationManager = (NotificationManager)GetSystemService(NotificationService);
            notificationManager.Notify(0, bui);
            StartForeground(121, bui);
            
        }

        public void CreateNotificationChannel()
        {
            if (Build.VERSION.SdkInt < BuildVersionCodes.O)
            {

                return;
            }

            var channelName = "Notification_Channel";
            var channelDescription = "Foreground Notification";
            var channel = new NotificationChannel("10121", channelName, NotificationImportance.High)
            {
                Description = channelDescription
            };

            var notificationManager = (NotificationManager)GetSystemService(NotificationService);
            notificationManager.CreateNotificationChannel(channel);
        }

到目前为止,我在应用程序设置中获得了通知渠道,但没有为我显示通知。我正在使用Redmi note 8 设备,我的目标 android 版本是 Android 11.0(API level 30)。我已经浏览了满足我要求的应用程序StepSetGo,您可以在 Playstore 中看到即使应用程序被杀死,应用程序也会持续显示通知,并且它会记录没有互联网的步数。我已经为此应用程序授予了相同的权限,例如自动启动并且没有电池限制,但它仍然无法正常工作。我不知道如何解决这个任何建议?

标签: c#androidxamarinxamarin.formsbackground-service

解决方案


广播接收器将与应用程序一起死亡。我会使用该服务来启动广播接收器并让它直接与服务对话。

为您服务: MyReceiver myreceiver = new MyReceiver(this); RegisterReceiver(myreceiver, new IntentFilter("com.example.MyReceiver");

在您的接收器中:

service.Notify("现在该起床了!");

另外,我注意到您的服务没有永久运行的通知。它将被操作系统杀死。

在您的服务中: StartForeground(intID, notification);


推荐阅读