即使应用程序关闭,Xamarin 也会为数据同步形成后台服务

Posted

技术标签:

【中文标题】即使应用程序关闭,Xamarin 也会为数据同步形成后台服务【英文标题】:Xamarin Forms Background Service For Data Sync Even If App Closes 【发布时间】:2020-06-09 23:05:38 【问题描述】:

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

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

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

谢谢

【问题讨论】:

如果你想在你的应用关闭的情况下运行服务,你需要创建一个前台服务 【参考方案1】:

如果你想在你的应用程序关闭一段时间后运行你的后台功能,我们需要创建一个前台服务。我说的是安卓。

首先在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 中,您可以通过共享项目中的消息中心调用来启动服务。我们还需要创建一个通知通道。

将此添加到您的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");      
        

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

【讨论】:

感谢@Anand 的帮助

以上是关于即使应用程序关闭,Xamarin 也会为数据同步形成后台服务的主要内容,如果未能解决你的问题,请参考以下文章

即使禁用 csrf,Spring Boot 也会为移动请求抛出 403

即使浏览器关闭,服务人员也会在后台运行吗?

在 Python 中,即使键存在,编译器也会为 datetimeIndex 函数抛出键错误

为啥即使指定了所有值,Spark SQL 也会为字符串列打开可为空?

在Xamarin.Forms应用程序中离开页面后,Webview不会关闭

即使用户有一些播放列表,Spotify Web API 也会为用户播放列表返回空项目