c# - 即使应用程序关闭,Xamarin Forms 后台服务也可实现数据同步

标签 c# xamarin xamarin.forms xamarin.android backgrounding

我想创建一个在后台运行的服务,即使我的应用程序因 Sqlite 和 mysql 的数据同步而关闭。

我尝试了一些方法,但无法实现我的目标。

如果有人可以给我一个示例应用程序,即使应用程序关闭,它也会在后台运行服务

谢谢

最佳答案

如果您希望即使在应用程序在一定时间间隔内关闭后也能运行后台功能,我们需要创建一个前台服务。我说的是安卓。

首先在Android项目文件夹中创建一个服务类。这里我创建一个名为SqlService的服务。

  [Service]
    class SqlService : Service
    {
        internal static readonly string CHANNEL_ID = "my_notification_channel";
        internal static readonly int NOTIFICATION_ID = 100;
        public override IBinder OnBind(Intent intent)
        {
            return null;
        }
        /*
         * This service will run until stopped explicitly because we are returning sticky
         */
        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            Toast.MakeText(this, "Service started", ToastLength.Long).Show();
            StartServiceInForeground();
            return StartCommandResult.Sticky;
        }
        /*
         * When our service is to be destroyed, show a Toast message before the destruction.
         */
        public override void OnDestroy()
        {
            base.OnDestroy();
            Toast.MakeText(this, "Syncing stopped", ToastLength.Long).Show();
        }

        void StartServiceInForeground()
        {

            if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
            {
                var intent = new Intent(this, typeof(MainActivity));

                var channel = new NotificationChannel(CHANNEL_ID, "Service Channel", NotificationImportance.High)
                {
                    Description = "Foreground Service Channel"
                };

                var notificationManager = (NotificationManager)GetSystemService(NotificationService);
                notificationManager.CreateNotificationChannel(channel);
                var pendingIntent = PendingIntent.GetActivity(this, MainActivity.NOTIFICATION_ID, intent, PendingIntentFlags.Immutable);
                var notification = new Notification.Builder(this, CHANNEL_ID)
                .SetContentTitle("My Sql App")
                .SetContentText("Sql Sync is on")
                .SetContentIntent(pendingIntent)
                .SetSmallIcon(Resource.Drawable.sr_notification)                
                .SetOngoing(true)
                .Build();
                 StartForeground(NOTIFICATION_ID, notification);
            }



            Device.StartTimer(TimeSpan.FromSeconds(300),  () =>
            {

                try
                {

                  //.. Do your sql syncing here 

                }

                catch (Exception ex)
                {

                }
                return true;
            });
        }

    }

在您的 MainActivity 中,您可以通过使用共享项目中的消息中心调用来启动服务。我们还需要创建一个通知 channel 。

将其添加到您的MainActivity

 public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {       
        internal static readonly string CHANNEL_ID = "my_notification_channel";
        internal static readonly int NOTIFICATION_ID = 100;

       protected override void OnCreate(Bundle savedInstanceState)
        {       
            base.OnCreate(savedInstanceState);         
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());
            CreateNotificationChannel();
            loadservice();      
        }




            void CreateNotificationChannel()
        {
            if (Build.VERSION.SdkInt < BuildVersionCodes.O)
            {
                // Notification channels are new in API 26 (and not a part of the
                // support library). There is no need to create a notification 
                // channel on older versions of Android.
                return;
            }

            var channel = new NotificationChannel(CHANNEL_ID, "FCM Notifications", NotificationImportance.Default)
            {
                Description = "Firebase Cloud Messages appear in this channel",
            };
            channel.EnableVibration(true);
            channel.EnableLights(true);

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


            private void loadservice()
        {

            MessagingCenter.Subscribe<Object>(this, "StartLongRunningTaskMessage", (sender) => {
                Intent myIntent = new Intent(this, typeof(LocationService));
                this.StartService(myIntent);
            });

            MessagingCenter.Subscribe<Object>(this, "StopLongRunningTaskMessage", (sender) => {
                Intent myIntent = new Intent(this, typeof(LocationService));
                this.StopService(myIntent);
            });
        }
}

现在您可以从共享项目启动服务,例如,单击按钮即可。

  private async void Sync_Clicked(object sender, EventArgs e)
    {
     MessagingCenter.Send<Object>(new Object(), "StartLongRunningTaskMessage");     
    }

我们还可以通过单击另一个按钮来停止服务,例如:

  private async void Sync_Clicked(object sender, EventArgs e)
        {
         MessagingCenter.Send<Object>(new Object(), "StopLongRunningTaskMessage");      
        }

如果您有任何疑问,请返回。

关于c# - 即使应用程序关闭,Xamarin Forms 后台服务也可实现数据同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62293280/

相关文章:

android - 适用于 Android/iOS/WinPhone 的 Xamarin 共性层

c# - Xamarin 自定义键盘

c# - 如何从 Xamarin Forms View 创建 native UWP View ?

c# - 如何为 Xamarin 表单标签添加边框?

Xamarin.Forms 自动完成跨平台

c# - 为什么 Visual Studio 2010 (Intellisense) 会停止生成接口(interface)指针?

c# - 休眠Linq

c# - 如何打开我的计算机并立即使用 C# 执行我的程序?

c# - 静态变量在 ASP.NET 页面中的什么地方起作用?

android - ZXing.Net.Mobile 的 Xamarin.Android 相机权限仅在应用重启后有效